diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index 8340532fcaf..9628e6b855d 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -49,3 +49,4 @@ - Update `fleet.kibana.path` from a POLICY_CHANGE {pull}21804[21804] - Removed `install-service.ps1` and `uninstall-service.ps1` from Windows .zip packaging {pull}21694[21694] - Add `priority` to `AddOrUpdate` on dynamic composable input providers communication channel {pull}22352[22352] +- Ship `endpoint-security` logs to elasticsearch {pull}22526[22526] diff --git a/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go b/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go index e96296016a4..888433ea0bc 100644 --- a/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go +++ b/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go @@ -43,12 +43,12 @@ func (u *Upgrader) downloadArtifact(ctx context.Context, version, sourceURI stri return "", errors.New(err, "initiating fetcher") } - path, err := fetcher.Download(ctx, agentName, agentArtifactName, version) + path, err := fetcher.Download(ctx, agentSpec, version) if err != nil { return "", errors.New(err, "failed upgrade of agent binary") } - matches, err := verifier.Verify(agentName, version, agentArtifactName, true) + matches, err := verifier.Verify(agentSpec, version, true) if err != nil { return "", errors.New(err, "failed verification of agent binary") } diff --git a/x-pack/elastic-agent/pkg/agent/application/upgrade/upgrade.go b/x-pack/elastic-agent/pkg/agent/application/upgrade/upgrade.go index d7e69fc3972..a96afd34686 100644 --- a/x-pack/elastic-agent/pkg/agent/application/upgrade/upgrade.go +++ b/x-pack/elastic-agent/pkg/agent/application/upgrade/upgrade.go @@ -18,6 +18,7 @@ import ( "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/install" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/logger" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/state" @@ -26,10 +27,17 @@ import ( ) const ( - agentName = "elastic-agent" - hashLen = 6 - agentCommitFile = ".elastic-agent.active.commit" - agentArtifactName = "beats/" + agentName + agentName = "elastic-agent" + hashLen = 6 + agentCommitFile = ".elastic-agent.active.commit" +) + +var ( + agentSpec = program.Spec{ + Name: "Elastic Agent", + Cmd: agentName, + Artifact: "beats/" + agentName, + } ) // Upgrader performs an upgrade diff --git a/x-pack/elastic-agent/pkg/agent/operation/common_test.go b/x-pack/elastic-agent/pkg/agent/operation/common_test.go index ea16cfe77b8..e216f463a60 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/common_test.go +++ b/x-pack/elastic-agent/pkg/agent/operation/common_test.go @@ -79,7 +79,7 @@ func getTestOperator(t *testing.T, downloadPath string, installPath string, p *a // make the download path so the `operation_verify` can ensure the path exists downloadConfig := operator.config.DownloadConfig - fullPath, err := artifact.GetArtifactPath(p.BinaryName(), p.Version(), downloadConfig.OS(), downloadConfig.Arch(), downloadConfig.TargetDirectory) + fullPath, err := artifact.GetArtifactPath(p.Spec(), p.Version(), downloadConfig.OS(), downloadConfig.Arch(), downloadConfig.TargetDirectory) if err != nil { t.Fatal(err) } @@ -137,7 +137,7 @@ func waitFor(t *testing.T, check func() error) { type DummyDownloader struct{} -func (*DummyDownloader) Download(_ context.Context, p, a, v string) (string, error) { +func (*DummyDownloader) Download(_ context.Context, _ program.Spec, _ string) (string, error) { return "", nil } @@ -145,7 +145,7 @@ var _ download.Downloader = &DummyDownloader{} type DummyVerifier struct{} -func (*DummyVerifier) Verify(p, v, _ string, _ bool) (bool, error) { +func (*DummyVerifier) Verify(_ program.Spec, _ string, _ bool) (bool, error) { return true, nil } @@ -153,11 +153,11 @@ var _ download.Verifier = &DummyVerifier{} type DummyInstallerChecker struct{} -func (*DummyInstallerChecker) Check(_ context.Context, p, v, _ string) error { +func (*DummyInstallerChecker) Check(_ context.Context, _ program.Spec, _, _ string) error { return nil } -func (*DummyInstallerChecker) Install(_ context.Context, p, v, _ string) error { +func (*DummyInstallerChecker) Install(_ context.Context, _ program.Spec, _, _ string) error { return nil } @@ -165,7 +165,7 @@ var _ install.InstallerChecker = &DummyInstallerChecker{} type DummyUninstaller struct{} -func (*DummyUninstaller) Uninstall(_ context.Context, p, v, _ string) error { +func (*DummyUninstaller) Uninstall(_ context.Context, _ program.Spec, _, _ string) error { return nil } diff --git a/x-pack/elastic-agent/pkg/agent/operation/monitoring.go b/x-pack/elastic-agent/pkg/agent/operation/monitoring.go index 1959cd52818..2cd2c339682 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/monitoring.go +++ b/x-pack/elastic-agent/pkg/agent/operation/monitoring.go @@ -344,7 +344,7 @@ func (o *Operator) getLogFilePaths() map[string][]string { defer o.appsLock.Unlock() for _, a := range o.apps { - logPath := a.Monitor().LogPath(a.Name(), o.pipelineID) + logPath := a.Monitor().LogPath(a.Spec(), o.pipelineID) if logPath != "" { paths[a.Name()] = append(paths[a.Name()], logPath) } @@ -360,7 +360,7 @@ func (o *Operator) getMetricbeatEndpoints() map[string][]string { defer o.appsLock.Unlock() for _, a := range o.apps { - metricEndpoint := a.Monitor().MetricsPathPrefixed(a.Name(), o.pipelineID) + metricEndpoint := a.Monitor().MetricsPathPrefixed(a.Spec(), o.pipelineID) if metricEndpoint != "" { endpoints[a.Name()] = append(endpoints[a.Name()], metricEndpoint) } diff --git a/x-pack/elastic-agent/pkg/agent/operation/monitoring_test.go b/x-pack/elastic-agent/pkg/agent/operation/monitoring_test.go index 3ca6a5f6b14..52ff0e6f200 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/monitoring_test.go +++ b/x-pack/elastic-agent/pkg/agent/operation/monitoring_test.go @@ -9,6 +9,8 @@ import ( "testing" "time" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" + "github.com/elastic/elastic-agent-client/v7/pkg/proto" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/info" @@ -154,6 +156,7 @@ func (*testMonitorableApp) Shutdown() {} func (*testMonitorableApp) Configure(_ context.Context, config map[string]interface{}) error { return nil } +func (*testMonitorableApp) Spec() program.Spec { return program.Spec{} } func (*testMonitorableApp) State() state.State { return state.State{} } func (*testMonitorableApp) SetState(_ state.Status, _ string, _ map[string]interface{}) {} func (a *testMonitorableApp) Monitor() monitoring.Monitor { return a.monitor } @@ -167,20 +170,22 @@ type testMonitor struct { // EnrichArgs enriches arguments provided to application, in order to enable // monitoring -func (b *testMonitor) EnrichArgs(_ string, _ string, args []string, _ bool) []string { return args } +func (b *testMonitor) EnrichArgs(_ program.Spec, _ string, args []string, _ bool) []string { + return args +} // Cleanup cleans up all drops. -func (b *testMonitor) Cleanup(string, string) error { return nil } +func (b *testMonitor) Cleanup(program.Spec, string) error { return nil } // Close closes the monitor. func (b *testMonitor) Close() {} // Prepare executes steps in order for monitoring to work correctly -func (b *testMonitor) Prepare(string, string, int, int) error { return nil } +func (b *testMonitor) Prepare(program.Spec, string, int, int) error { return nil } // LogPath describes a path where application stores logs. Empty if // application is not monitorable -func (b *testMonitor) LogPath(string, string) string { +func (b *testMonitor) LogPath(program.Spec, string) string { if !b.monitorLogs { return "" } @@ -189,7 +194,7 @@ func (b *testMonitor) LogPath(string, string) string { // MetricsPath describes a location where application exposes metrics // collectable by metricbeat. -func (b *testMonitor) MetricsPath(string, string) string { +func (b *testMonitor) MetricsPath(program.Spec, string) string { if !b.monitorMetrics { return "" } @@ -197,7 +202,7 @@ func (b *testMonitor) MetricsPath(string, string) string { } // MetricsPathPrefixed return metrics path prefixed with http+ prefix. -func (b *testMonitor) MetricsPathPrefixed(string, string) string { +func (b *testMonitor) MetricsPathPrefixed(program.Spec, string) string { return "http+path" } diff --git a/x-pack/elastic-agent/pkg/agent/operation/operation.go b/x-pack/elastic-agent/pkg/agent/operation/operation.go index caa2f8abf40..eb47d053772 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/operation.go +++ b/x-pack/elastic-agent/pkg/agent/operation/operation.go @@ -10,6 +10,7 @@ import ( "github.com/elastic/elastic-agent-client/v7/pkg/proto" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/app" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/monitoring" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/server" @@ -42,6 +43,7 @@ type Application interface { Configure(ctx context.Context, config map[string]interface{}) error Monitor() monitoring.Monitor State() state.State + Spec() program.Spec SetState(status state.Status, msg string, payload map[string]interface{}) OnStatusChange(s *server.ApplicationState, status proto.StateObserved_Status, msg string, payload map[string]interface{}) } @@ -49,6 +51,7 @@ type Application interface { // Descriptor defines a program which needs to be run. // Is passed around operator operations. type Descriptor interface { + Spec() program.Spec ServicePort() int BinaryName() string ArtifactName() string diff --git a/x-pack/elastic-agent/pkg/agent/operation/operation_fetch.go b/x-pack/elastic-agent/pkg/agent/operation/operation_fetch.go index 97bc5d279de..0f66842abce 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/operation_fetch.go +++ b/x-pack/elastic-agent/pkg/agent/operation/operation_fetch.go @@ -48,7 +48,7 @@ func (o *operationFetch) Name() string { // If the artifacts already exists then fetch will not be ran. func (o *operationFetch) Check(_ context.Context, _ Application) (bool, error) { downloadConfig := o.operatorConfig.DownloadConfig - fullPath, err := artifact.GetArtifactPath(o.program.BinaryName(), o.program.Version(), downloadConfig.OS(), downloadConfig.Arch(), downloadConfig.TargetDirectory) + fullPath, err := artifact.GetArtifactPath(o.program.Spec(), o.program.Version(), downloadConfig.OS(), downloadConfig.Arch(), downloadConfig.TargetDirectory) if err != nil { return false, err } @@ -70,7 +70,7 @@ func (o *operationFetch) Run(ctx context.Context, application Application) (err } }() - fullPath, err := o.downloader.Download(ctx, o.program.BinaryName(), o.program.ArtifactName(), o.program.Version()) + fullPath, err := o.downloader.Download(ctx, o.program.Spec(), o.program.Version()) if err == nil { o.logger.Infof("operation '%s' downloaded %s.%s into %s", o.Name(), o.program.BinaryName(), o.program.Version(), fullPath) } diff --git a/x-pack/elastic-agent/pkg/agent/operation/operation_install.go b/x-pack/elastic-agent/pkg/agent/operation/operation_install.go index d5a22db1fd9..9eb439ad894 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/operation_install.go +++ b/x-pack/elastic-agent/pkg/agent/operation/operation_install.go @@ -45,7 +45,7 @@ func (o *operationInstall) Name() string { // // If the installation directory already exists then it will not be ran. func (o *operationInstall) Check(ctx context.Context, _ Application) (bool, error) { - err := o.installer.Check(ctx, o.program.BinaryName(), o.program.Version(), o.program.Directory()) + err := o.installer.Check(ctx, o.program.Spec(), o.program.Version(), o.program.Directory()) if err != nil { // don't return err, just state if Run should be called return true, nil @@ -61,5 +61,5 @@ func (o *operationInstall) Run(ctx context.Context, application Application) (er } }() - return o.installer.Install(ctx, o.program.BinaryName(), o.program.Version(), o.program.Directory()) + return o.installer.Install(ctx, o.program.Spec(), o.program.Version(), o.program.Directory()) } diff --git a/x-pack/elastic-agent/pkg/agent/operation/operation_uninstall.go b/x-pack/elastic-agent/pkg/agent/operation/operation_uninstall.go index de8f797f8ef..744bf828046 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/operation_uninstall.go +++ b/x-pack/elastic-agent/pkg/agent/operation/operation_uninstall.go @@ -51,5 +51,5 @@ func (o *operationUninstall) Run(ctx context.Context, application Application) ( } }() - return o.uninstaller.Uninstall(ctx, o.program.BinaryName(), o.program.Version(), o.program.Directory()) + return o.uninstaller.Uninstall(ctx, o.program.Spec(), o.program.Version(), o.program.Directory()) } diff --git a/x-pack/elastic-agent/pkg/agent/operation/operation_verify.go b/x-pack/elastic-agent/pkg/agent/operation/operation_verify.go index 7626d339e57..daf72606d85 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/operation_verify.go +++ b/x-pack/elastic-agent/pkg/agent/operation/operation_verify.go @@ -45,7 +45,7 @@ func (o *operationVerify) Name() string { // Only if the artifacts exists does it need to be verified. func (o *operationVerify) Check(_ context.Context, _ Application) (bool, error) { downloadConfig := o.operatorConfig.DownloadConfig - fullPath, err := artifact.GetArtifactPath(o.program.BinaryName(), o.program.Version(), downloadConfig.OS(), downloadConfig.Arch(), downloadConfig.TargetDirectory) + fullPath, err := artifact.GetArtifactPath(o.program.Spec(), o.program.Version(), downloadConfig.OS(), downloadConfig.Arch(), downloadConfig.TargetDirectory) if err != nil { return false, err } @@ -66,7 +66,7 @@ func (o *operationVerify) Run(_ context.Context, application Application) (err e } }() - isVerified, err := o.verifier.Verify(o.program.BinaryName(), o.program.Version(), o.program.ArtifactName(), true) + isVerified, err := o.verifier.Verify(o.program.Spec(), o.program.Version(), true) if err != nil { return errors.New(err, fmt.Sprintf("operation '%s' failed to verify %s.%s", o.Name(), o.program.BinaryName(), o.program.Version()), diff --git a/x-pack/elastic-agent/pkg/agent/operation/operator.go b/x-pack/elastic-agent/pkg/agent/operation/operator.go index 1a39e73500e..c302db1ecc7 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/operator.go +++ b/x-pack/elastic-agent/pkg/agent/operation/operator.go @@ -256,9 +256,9 @@ func (o *Operator) getApp(p Descriptor) (Application, error) { return a, nil } - specifier, ok := p.(app.Specifier) + desc, ok := p.(*app.Descriptor) if !ok { - return nil, fmt.Errorf("descriptor is not an app.Specifier") + return nil, fmt.Errorf("descriptor is not an app.Descriptor") } // TODO: (michal) join args into more compact options version @@ -272,7 +272,7 @@ func (o *Operator) getApp(p Descriptor) (Application, error) { p.BinaryName(), o.pipelineID, o.config.LoggingConfig.Level.String(), - specifier, + desc, o.srv, o.config, o.logger, @@ -288,7 +288,7 @@ func (o *Operator) getApp(p Descriptor) (Application, error) { o.pipelineID, o.config.LoggingConfig.Level.String(), p.ServicePort(), - specifier, + desc, o.srv, o.config, o.logger, diff --git a/x-pack/elastic-agent/pkg/agent/operation/operator_test.go b/x-pack/elastic-agent/pkg/agent/operation/operator_test.go index e178620d228..794dbdb5805 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/operator_test.go +++ b/x-pack/elastic-agent/pkg/agent/operation/operator_test.go @@ -390,7 +390,7 @@ func TestConfigurableService(t *testing.T) { defer operator.stop(p) // failure catch, to ensure no sub-process stays running // emulating a service, so we need to start the binary here in the test - spec := p.Spec() + spec := p.ProcessSpec() cmd := exec.Command(spec.BinaryPath, fmt.Sprintf("%d", p.ServicePort())) cmd.Env = append(cmd.Env, os.Environ()...) cmd.Dir = filepath.Dir(spec.BinaryPath) @@ -445,7 +445,7 @@ func TestConfigurableService(t *testing.T) { func isAvailable(name, version string) error { p := getProgram(name, version) - spec := p.Spec() + spec := p.ProcessSpec() path := spec.BinaryPath if runtime.GOOS == "windows" { path += ".exe" diff --git a/x-pack/elastic-agent/pkg/agent/program/spec.go b/x-pack/elastic-agent/pkg/agent/program/spec.go index 5646a3652e9..2ae1d698dba 100644 --- a/x-pack/elastic-agent/pkg/agent/program/spec.go +++ b/x-pack/elastic-agent/pkg/agent/program/spec.go @@ -32,6 +32,8 @@ type Spec struct { Cmd string `yaml:"cmd"` Args []string `yaml:"args"` Artifact string `yaml:"artifact"` + LogPaths map[string]string `yaml:"log_paths,omitempty"` + MetricEndpoints map[string]string `yaml:"metric_endpoints,omitempty"` Rules *transpiler.RuleList `yaml:"rules"` CheckInstallSteps *transpiler.StepList `yaml:"check_install"` PostInstallSteps *transpiler.StepList `yaml:"post_install"` diff --git a/x-pack/elastic-agent/pkg/agent/program/supported.go b/x-pack/elastic-agent/pkg/agent/program/supported.go index 67e094a2074..0971c3ffbdd 100644 --- a/x-pack/elastic-agent/pkg/agent/program/supported.go +++ b/x-pack/elastic-agent/pkg/agent/program/supported.go @@ -21,7 +21,7 @@ func init() { // spec/filebeat.yml // spec/heartbeat.yml // spec/metricbeat.yml - unpacked := packer.MustUnpack("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") + unpacked := packer.MustUnpack("eJy8WFtzq7p3f+/HOK//TgsiTktnzoMh5WabbJMECb0hyQZsgTkxYEOn370jwFycZO+zu/+zHzK2iZCWltb6XfQ/f5zzHf33XcbyU5IV/1an/I//+oOkRoFfT5EHF0dqqjnJttEb8A8MOTmzjqsAyMfnROMk9S4E8JLpcoOhK9OUS7ttHtPMy3FqHNjTKcLjHAU2faBnLqcZzgPw9mg/BcrzU7QippohRYuZGTfP0SmyTS+mGcvJ4RTZiboJoVMHyFmsJf8cIFcK4aaaxFZRxYuZ+VaJedbAL7GlVSFcSOuXUyme2e2c15xk/sNzskzWQL0wXTWIaTTM5Ie1NHlHcaUAeXwNrhWu1ckepb/WqXhmr2xdU0K4OBKFNWK+bZNTZGg1AawOoBR5KT9j5FL037d42+/DGsi4Nsw0JOxfabt34/rpOgGIeQCKfQgXYvyZPJ1W6xeN70z/gADOifn2qCfLyNa1S4C8k4hlmm86nlnSj4tpyroc68to/bJMWOrXIcQLu3/GTF5gqMri7DbNckVNtWGGmM+VAng9P0enwjb9BwzdPRb7fD2txHu2Jc4verR15/O6eLG7caZRY2XTx70sbN0Z5rYnca1fZJmaIp8ev3teY+RWDDkHjDbJZJ4v1p2NL3cpv3y2V/ewvOiZVmNflUnKS1FTxLw86okUYRTzQFbTEF75LXfUNKTw6RTZ6aR2kMsDxa9D5A35DJCT0abP0S3ncPFhzx9jcWRi+k2Xb5zvDLVhlsMDKD3aVqHq/XNieZxyFQTwKmN0y6vWYHjlgeJV9HCKQri4MOQ1/f/eMTo+2pa3oOZbf3Y4JpbPxzilad+u2hyk/MxMv0bK3VjL5cT0D8xU6+dEy0mmycza9Gdd8N1riwFxkF45XvZ7TY0zg/6kDjWJZj5v93Sbr605rxryDfwzhq5EFKd5TjSCxXxoWwbQPWDkNggYl9BXxd7OtonPGPrSOi3yIDXKwJfmNTr837iE27anigAt73pJS4npc9bHTDP/POZ3WdiWwwlUAe7WvD1v/0LgL54TLQ6Ay6ni7gOk5QgUfLcd9ltjKFcs9fft2H6P05yFgCcBXMSzcz58zPnszLqcDL/n574sbFOVmaXJtz21cSCcU8ArEp1WDMRcYC4x/RIr3mmle//Rzempq5flP+ynZRTAxdE2BV4xKdSj4w7wklq+RBUpt58eoo2uxSTdRqFpNC/AX4g5iOJLYsz+5RI5YMDEBkOjDkCUrbanP//4146K9gnfkV34gYoE1ECHB2h7o5+2HYPUj9ky72At0YidyIadXCI7czmz/Ms65WfysuAkNRJi+sdvUJSvy9sx92MzjxOknVv4T/0ygM4Zw62KU+NMwVuy1pfJ+q37JNAoA8g4gX7J9EVBgMe/oaigpnEIa7krHd0+27pdeC/i0ynEcWLgF1hAxWR+ZjkyfpmNPRPAshAusnV65Sz1z9+gx4PMz2wurQLkSCHEcaBsH21T5MRr1i0d+AmGhvRD6Eja0vhLtBMCvMSm/3ArQWbxi8i3oCV6aVsjJ2kuoGRPFa/G0CiQIqiuLe1qKElTLRFwK5LicwhdqYMCQfXePoBYwqiH/w52Hm3zWmFl00ILgcblHlbvIKtm8DqDpwCol52vxsS87pmp7onJG/Y0wqytaxJpTtEtZnqZttiHWEsC1Mu0hTGKDxhpUltTmSvR1I8J2rRnH8Jt+znAWnvOzoWmagtFAqLEOd3FKhFZPYfIlebtziXcnsskp9nm/7uPMeepnxLF6SFVUGPbR/1Z4ZoA6dE2+9a93CjoP8dnyrDnVU+BEhWSzuj2gICIW26+Orf7eEPkcfL6cR+zNS9fQvGcVqyhvkf6SI2SgquQgTMovsXV1vV2mjs5ppY2Qurw/FrhXlq136f5busCcyE5e+nT9sl0PVvXRL+WTFcbZnqthKWKdwzhw906PmhxQPEOVMRnupcv5pGxtXy0Lf9Il/NYOrnrVQEoxD4ibKqHEPj13TxnAmhFU/8YIndPwbViQtqKmmqfbT7uv1abHXLFe4+25S7EO7c8/B3qYsjlCHxCNT94D5uGFPgDVg39Q1O/IArmLYW+znq8kzKmkP/GgE/rdBET6DcCi/FPUO7d+mX7G7lCAoi6FHwjYeTs7+XLKE3sDz3VSwFphzTe1/SdVBO0bCgUuGei+EcGDCkA0YgdKJdp+lZ0deedGLQnuHKtGPRSoggJ6izG+dyKZF4cwgWnY48cCXDfBxwWcgG4lzXS5CBz5WAcd2KWd0ETGzXOG0vM0v6iQC3HZ0WM0yIef89qpaDIm7y/4MzEZ6LQIQbSbIALDRmbXJpKK2zyUbZYm8l3V8ImLye/7+tTCpTlMD+D3mUc65chGnPLAG/t4S9LaXPg8i/ldMvx2zmftvoh84S9SwXG7xSpxdqWL/4WVk84/6dk4qilhnPoJdrkXPkOtXKb6xk7YfjwOJd949rr9Ncl4FpfZj0eZesWM9h7APF78ELPts6EHhIWuAl1muvRn4NcjHfhe/GJXnwx/ZhmXpeb1C2w4KbZs86G2sZ50HQU+BJDyzKE1+JH+u82lpl+Qc2Wd8pBDzzJaQCvzZ2mu9N/coXNN3Wny5cAuu9r2FmSmS5N5ZikRoahLDhnOn9rl+ZjBW+xnKS0JC23XFRs+gmDNEF3VzKtZrY21Swf2ZRT2xp5QDcN8NrVZlcX933i7hngUmioNYaM76zlyL83Pphxr1aL80GZuxB4hpGXB8qmWifnAde/xtPv2NAf4PCXvfqJHb3r2dm645gJLmSbmeZoe3yqV/TP7ddg04C/oGKe9O1TC3bDnP3LMfqWLC+2aZRY104BctcYHU+OVVQMeWKMKvoIw2tMFZFXlwfIOYR620M1hl5Oa3oWsTqgw22nFv0otLgruO7k1MfVrbfSXfGe0E+a6xX6Ek35oTdfBwKFEZE5s5w8AL1J6+49IlgPDdBg5MlUX+TElH7ULLexQmReiGlI+Ecm7q5ZCFSP+FV+WCPhw89F742/Z+LG+ZFXM3hn+Ew1w8Is1YtzS8ZP8hFDR8a1wwSYMJOnQSfC24aitVpg5NUhdPsG0yqqeLO7vK4oOlEyu0ub3S/JFbbau4cS660wE4ah3EF5uDsSJkHkG6PtowAaAry2mdfptqIKbwRIrTNeEH0hRODNtKzGO43PG35KViFcHDGKbqTYCprnRLvtsekIiJdh2t7d9CJK3lPLqQLgNxSoQ/MQsNgHQC1xes07E8tLCvyaGWqMM28QLYMZ7eutNwi1qB0Ch7vPlKZq8dEkeNX4zL3F08cpx/Tp7t7yE+Pzhdk4EEVbIGCcifGFqevWHtecgMPHvS8qMgiWTvjvTJdTa9uS02CY6rYv8t5sDrXaXWDMzGOCtnexKl6FwDWnynZ+T3UzZZMzmhnMn9rHcIYJhrgFs99sHD8IdKSwnJnxnqZ+hlE8XDJ8Iso7Ukoe3tegxzFlc/yuAPy9ovEXTbH/NUl/zyRbjujx3epJ3X7rLm7+sU7O+ccc9UQq1ng6Rc70brkzcGUAZT43Xb2wnY0dLzwEfjN45aMgleMQ+PsAOXVwf9/a18iAE2AQspNaucXs8pGY/465nLz3M2b27s779xrg9nczvQv+XSb6zvz/kw3PXGOId+9rC2dONa2FVqMIzfGRGwae/BnzNJt3PNtegE3u3iei7nMDNdtLeav3XzJRnXEahN4PTdT//sv/BQAA//8mtiC8") SupportedMap = make(map[string]Spec) for f, v := range unpacked { diff --git a/x-pack/elastic-agent/pkg/artifact/artifact.go b/x-pack/elastic-agent/pkg/artifact/artifact.go index b1dfb4d8a5e..7f4001e77e0 100644 --- a/x-pack/elastic-agent/pkg/artifact/artifact.go +++ b/x-pack/elastic-agent/pkg/artifact/artifact.go @@ -9,6 +9,7 @@ import ( "path/filepath" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" ) var packageArchMap = map[string]string{ @@ -21,19 +22,19 @@ var packageArchMap = map[string]string{ } // GetArtifactName constructs a path to a downloaded artifact -func GetArtifactName(programName, version, operatingSystem, arch string) (string, error) { +func GetArtifactName(spec program.Spec, version, operatingSystem, arch string) (string, error) { key := fmt.Sprintf("%s-binary-%s", operatingSystem, arch) suffix, found := packageArchMap[key] if !found { return "", errors.New(fmt.Sprintf("'%s' is not a valid combination for a package", key), errors.TypeConfig) } - return fmt.Sprintf("%s-%s-%s", programName, version, suffix), nil + return fmt.Sprintf("%s-%s-%s", spec.Cmd, version, suffix), nil } // GetArtifactPath returns a full path of artifact for a program in specific version -func GetArtifactPath(programName, version, operatingSystem, arch, targetDir string) (string, error) { - artifactName, err := GetArtifactName(programName, version, operatingSystem, arch) +func GetArtifactPath(spec program.Spec, version, operatingSystem, arch, targetDir string) (string, error) { + artifactName, err := GetArtifactName(spec, version, operatingSystem, arch) if err != nil { return "", err } diff --git a/x-pack/elastic-agent/pkg/artifact/download/composed/downloader.go b/x-pack/elastic-agent/pkg/artifact/download/composed/downloader.go index 9209c8e84c1..d500a1f8cc1 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/composed/downloader.go +++ b/x-pack/elastic-agent/pkg/artifact/download/composed/downloader.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/go-multierror" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/download" ) @@ -32,11 +33,11 @@ func NewDownloader(downloaders ...download.Downloader) *Downloader { // Download fetches the package from configured source. // Returns absolute path to downloaded package and an error. -func (e *Downloader) Download(ctx context.Context, programName, artifactName, version string) (string, error) { +func (e *Downloader) Download(ctx context.Context, spec program.Spec, version string) (string, error) { var err error for _, d := range e.dd { - s, e := d.Download(ctx, programName, artifactName, version) + s, e := d.Download(ctx, spec, version) if e == nil { return s, nil } diff --git a/x-pack/elastic-agent/pkg/artifact/download/composed/downloader_test.go b/x-pack/elastic-agent/pkg/artifact/download/composed/downloader_test.go index 34b4e658041..81e9af137dc 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/composed/downloader_test.go +++ b/x-pack/elastic-agent/pkg/artifact/download/composed/downloader_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/assert" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/download" ) @@ -18,7 +19,7 @@ type FailingDownloader struct { called bool } -func (d *FailingDownloader) Download(ctx context.Context, a, b, c string) (string, error) { +func (d *FailingDownloader) Download(ctx context.Context, _ program.Spec, _ string) (string, error) { d.called = true return "", errors.New("failing") } @@ -29,7 +30,7 @@ type SuccDownloader struct { called bool } -func (d *SuccDownloader) Download(ctx context.Context, a, b, c string) (string, error) { +func (d *SuccDownloader) Download(ctx context.Context, _ program.Spec, _ string) (string, error) { d.called = true return "succ", nil } @@ -58,7 +59,7 @@ func TestComposed(t *testing.T) { for _, tc := range testCases { d := NewDownloader(tc.downloaders[0], tc.downloaders[1]) - r, _ := d.Download(nil, "a", "b", "c") + r, _ := d.Download(nil, program.Spec{Name: "a", Cmd: "a", Artifact: "a/a"}, "b") assert.Equal(t, tc.expectedResult, r == "succ") diff --git a/x-pack/elastic-agent/pkg/artifact/download/composed/verifier.go b/x-pack/elastic-agent/pkg/artifact/download/composed/verifier.go index 663484130f4..4dbe5377b79 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/composed/verifier.go +++ b/x-pack/elastic-agent/pkg/artifact/download/composed/verifier.go @@ -7,6 +7,7 @@ package composed import ( "github.com/hashicorp/go-multierror" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/download" ) @@ -29,12 +30,12 @@ func NewVerifier(verifiers ...download.Verifier) *Verifier { } // Verify checks the package from configured source. -func (e *Verifier) Verify(programName, version, artifactName string, removeOnFailure bool) (bool, error) { +func (e *Verifier) Verify(spec program.Spec, version string, removeOnFailure bool) (bool, error) { var err error for i, v := range e.vv { isLast := (i + 1) == len(e.vv) - b, e := v.Verify(programName, version, artifactName, isLast && removeOnFailure) + b, e := v.Verify(spec, version, isLast && removeOnFailure) if e == nil { return b, nil } diff --git a/x-pack/elastic-agent/pkg/artifact/download/downloader.go b/x-pack/elastic-agent/pkg/artifact/download/downloader.go index 7bfbd4b7019..86e64e768ba 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/downloader.go +++ b/x-pack/elastic-agent/pkg/artifact/download/downloader.go @@ -4,9 +4,13 @@ package download -import "context" +import ( + "context" + + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" +) // Downloader is an interface allowing download of an artifact type Downloader interface { - Download(ctx context.Context, programName, artifactName, version string) (string, error) + Download(ctx context.Context, spec program.Spec, version string) (string, error) } diff --git a/x-pack/elastic-agent/pkg/artifact/download/fs/downloader.go b/x-pack/elastic-agent/pkg/artifact/download/fs/downloader.go index 04f4c667e02..b1bac639c51 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/fs/downloader.go +++ b/x-pack/elastic-agent/pkg/artifact/download/fs/downloader.go @@ -11,6 +11,8 @@ import ( "os" "path/filepath" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" @@ -36,7 +38,7 @@ func NewDownloader(config *artifact.Config) *Downloader { // Download fetches the package from configured source. // Returns absolute path to downloaded package and an error. -func (e *Downloader) Download(_ context.Context, programName, artifactName, version string) (_ string, err error) { +func (e *Downloader) Download(_ context.Context, spec program.Spec, version string) (_ string, err error) { downloadedFiles := make([]string, 0, 2) defer func() { if err != nil { @@ -47,24 +49,24 @@ func (e *Downloader) Download(_ context.Context, programName, artifactName, vers }() // download from source to dest - path, err := e.download(e.config.OS(), programName, artifactName, version) + path, err := e.download(e.config.OS(), spec, version) downloadedFiles = append(downloadedFiles, path) if err != nil { return "", err } - hashPath, err := e.downloadHash(e.config.OS(), programName, artifactName, version) + hashPath, err := e.downloadHash(e.config.OS(), spec, version) downloadedFiles = append(downloadedFiles, hashPath) return path, err } -func (e *Downloader) download(operatingSystem, programName, _, version string) (string, error) { - filename, err := artifact.GetArtifactName(programName, version, operatingSystem, e.config.Arch()) +func (e *Downloader) download(operatingSystem string, spec program.Spec, version string) (string, error) { + filename, err := artifact.GetArtifactName(spec, version, operatingSystem, e.config.Arch()) if err != nil { return "", errors.New(err, "generating package name failed") } - fullPath, err := artifact.GetArtifactPath(programName, version, operatingSystem, e.config.Arch(), e.config.TargetDirectory) + fullPath, err := artifact.GetArtifactPath(spec, version, operatingSystem, e.config.Arch(), e.config.TargetDirectory) if err != nil { return "", errors.New(err, "generating package path failed") } @@ -72,13 +74,13 @@ func (e *Downloader) download(operatingSystem, programName, _, version string) ( return e.downloadFile(filename, fullPath) } -func (e *Downloader) downloadHash(operatingSystem, programName, _, version string) (string, error) { - filename, err := artifact.GetArtifactName(programName, version, operatingSystem, e.config.Arch()) +func (e *Downloader) downloadHash(operatingSystem string, spec program.Spec, version string) (string, error) { + filename, err := artifact.GetArtifactName(spec, version, operatingSystem, e.config.Arch()) if err != nil { return "", errors.New(err, "generating package name failed") } - fullPath, err := artifact.GetArtifactPath(programName, version, operatingSystem, e.config.Arch(), e.config.TargetDirectory) + fullPath, err := artifact.GetArtifactPath(spec, version, operatingSystem, e.config.Arch(), e.config.TargetDirectory) if err != nil { return "", errors.New(err, "generating package path failed") } diff --git a/x-pack/elastic-agent/pkg/artifact/download/fs/verifier.go b/x-pack/elastic-agent/pkg/artifact/download/fs/verifier.go index 2fc5daedabf..333238da59b 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/fs/verifier.go +++ b/x-pack/elastic-agent/pkg/artifact/download/fs/verifier.go @@ -15,6 +15,8 @@ import ( "path/filepath" "strings" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" + "golang.org/x/crypto/openpgp" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" @@ -52,8 +54,8 @@ func NewVerifier(config *artifact.Config, allowEmptyPgp bool, pgp []byte) (*Veri // Verify checks downloaded package on preconfigured // location agains a key stored on elastic.co website. -func (v *Verifier) Verify(programName, version, artifactName string, removeOnFailure bool) (isMatch bool, err error) { - filename, err := artifact.GetArtifactName(programName, version, v.config.OS(), v.config.Arch()) +func (v *Verifier) Verify(spec program.Spec, version string, removeOnFailure bool) (isMatch bool, err error) { + filename, err := artifact.GetArtifactName(spec, version, v.config.OS(), v.config.Arch()) if err != nil { return false, errors.New(err, "retrieving package name") } diff --git a/x-pack/elastic-agent/pkg/artifact/download/fs/verifier_test.go b/x-pack/elastic-agent/pkg/artifact/download/fs/verifier_test.go index a79f35bdd6f..38d17dadf4c 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/fs/verifier_test.go +++ b/x-pack/elastic-agent/pkg/artifact/download/fs/verifier_test.go @@ -16,13 +16,16 @@ import ( "github.com/stretchr/testify/assert" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" ) const ( - beatName = "filebeat" - artifactName = "beats/filebeat" - version = "7.5.1" + version = "7.5.1" +) + +var ( + beatSpec = program.Spec{Name: "Filebeat", Cmd: "filebeat", Artifact: "beat/filebeat"} ) type testCase struct { @@ -36,8 +39,7 @@ func TestFetchVerify(t *testing.T) { installPath := filepath.Join("testdata", "install") targetPath := filepath.Join("testdata", "download") ctx := context.Background() - programName := "beat" - artifactName := "beats/beat" + s := program.Spec{Name: "Beat", Cmd: "beat", Artifact: "beats/filebeat"} version := "8.0.0" targetFilePath := filepath.Join(targetPath, "beat-8.0.0-darwin-x86_64.tar.gz") @@ -65,7 +67,7 @@ func TestFetchVerify(t *testing.T) { // first download verify should fail: // download skipped, as invalid package is prepared upfront // verify fails and cleans download - matches, err := verifier.Verify(programName, version, artifactName, true) + matches, err := verifier.Verify(s, version, true) assert.NoError(t, err) assert.Equal(t, false, matches) @@ -78,7 +80,7 @@ func TestFetchVerify(t *testing.T) { // second one should pass // download not skipped: package missing // verify passes because hash is not correct - _, err = downloader.Download(ctx, programName, artifactName, version) + _, err = downloader.Download(ctx, s, version) assert.NoError(t, err) // file downloaded ok @@ -88,7 +90,7 @@ func TestFetchVerify(t *testing.T) { _, err = os.Stat(hashTargetFilePath) assert.NoError(t, err) - matches, err = verifier.Verify(programName, version, artifactName, true) + matches, err = verifier.Verify(s, version, true) assert.NoError(t, err) assert.Equal(t, true, matches) } @@ -142,12 +144,12 @@ func TestVerify(t *testing.T) { Architecture: "32", } - if err := prepareTestCase(beatName, version, config); err != nil { + if err := prepareTestCase(beatSpec, version, config); err != nil { t.Fatal(err) } testClient := NewDownloader(config) - artifact, err := testClient.Download(context.Background(), beatName, artifactName, version) + artifact, err := testClient.Download(context.Background(), beatSpec, version) if err != nil { t.Fatal(err) } @@ -162,7 +164,7 @@ func TestVerify(t *testing.T) { t.Fatal(err) } - isOk, err := testVerifier.Verify(beatName, version, artifactName, true) + isOk, err := testVerifier.Verify(beatSpec, version, true) if err != nil { t.Fatal(err) } @@ -176,8 +178,8 @@ func TestVerify(t *testing.T) { os.RemoveAll(config.DropPath) } -func prepareTestCase(beatName, version string, cfg *artifact.Config) error { - filename, err := artifact.GetArtifactName(beatName, version, cfg.OperatingSystem, cfg.Architecture) +func prepareTestCase(beatSpec program.Spec, version string, cfg *artifact.Config) error { + filename, err := artifact.GetArtifactName(beatSpec, version, cfg.OperatingSystem, cfg.Architecture) if err != nil { return err } diff --git a/x-pack/elastic-agent/pkg/artifact/download/http/downloader.go b/x-pack/elastic-agent/pkg/artifact/download/http/downloader.go index 4af71eca0db..1e11c92d796 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/http/downloader.go +++ b/x-pack/elastic-agent/pkg/artifact/download/http/downloader.go @@ -14,6 +14,8 @@ import ( "path" "strings" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/release" @@ -51,7 +53,7 @@ func NewDownloaderWithClient(config *artifact.Config, client http.Client) *Downl // Download fetches the package from configured source. // Returns absolute path to downloaded package and an error. -func (e *Downloader) Download(ctx context.Context, programName, artifactName, version string) (_ string, err error) { +func (e *Downloader) Download(ctx context.Context, spec program.Spec, version string) (_ string, err error) { downloadedFiles := make([]string, 0, 2) defer func() { if err != nil { @@ -62,13 +64,13 @@ func (e *Downloader) Download(ctx context.Context, programName, artifactName, ve }() // download from source to dest - path, err := e.download(ctx, e.config.OS(), programName, artifactName, version) + path, err := e.download(ctx, e.config.OS(), spec, version) downloadedFiles = append(downloadedFiles, path) if err != nil { return "", err } - hashPath, err := e.downloadHash(ctx, e.config.OS(), programName, artifactName, version) + hashPath, err := e.downloadHash(ctx, e.config.OS(), spec, version) downloadedFiles = append(downloadedFiles, hashPath) return path, err } @@ -90,27 +92,27 @@ func (e *Downloader) composeURI(artifactName, packageName string) (string, error return uri.String(), nil } -func (e *Downloader) download(ctx context.Context, operatingSystem, programName, artifactName, version string) (string, error) { - filename, err := artifact.GetArtifactName(programName, version, operatingSystem, e.config.Arch()) +func (e *Downloader) download(ctx context.Context, operatingSystem string, spec program.Spec, version string) (string, error) { + filename, err := artifact.GetArtifactName(spec, version, operatingSystem, e.config.Arch()) if err != nil { return "", errors.New(err, "generating package name failed") } - fullPath, err := artifact.GetArtifactPath(programName, version, operatingSystem, e.config.Arch(), e.config.TargetDirectory) + fullPath, err := artifact.GetArtifactPath(spec, version, operatingSystem, e.config.Arch(), e.config.TargetDirectory) if err != nil { return "", errors.New(err, "generating package path failed") } - return e.downloadFile(ctx, artifactName, filename, fullPath) + return e.downloadFile(ctx, spec.Artifact, filename, fullPath) } -func (e *Downloader) downloadHash(ctx context.Context, operatingSystem, programName, artifactName, version string) (string, error) { - filename, err := artifact.GetArtifactName(programName, version, operatingSystem, e.config.Arch()) +func (e *Downloader) downloadHash(ctx context.Context, operatingSystem string, spec program.Spec, version string) (string, error) { + filename, err := artifact.GetArtifactName(spec, version, operatingSystem, e.config.Arch()) if err != nil { return "", errors.New(err, "generating package name failed") } - fullPath, err := artifact.GetArtifactPath(programName, version, operatingSystem, e.config.Arch(), e.config.TargetDirectory) + fullPath, err := artifact.GetArtifactPath(spec, version, operatingSystem, e.config.Arch(), e.config.TargetDirectory) if err != nil { return "", errors.New(err, "generating package path failed") } @@ -118,7 +120,7 @@ func (e *Downloader) downloadHash(ctx context.Context, operatingSystem, programN filename = filename + ".sha512" fullPath = fullPath + ".sha512" - return e.downloadFile(ctx, artifactName, filename, fullPath) + return e.downloadFile(ctx, spec.Artifact, filename, fullPath) } func (e *Downloader) downloadFile(ctx context.Context, artifactName, filename, fullPath string) (string, error) { diff --git a/x-pack/elastic-agent/pkg/artifact/download/http/elastic_test.go b/x-pack/elastic-agent/pkg/artifact/download/http/elastic_test.go index 0ff4dfd2b93..e2097a9297f 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/http/elastic_test.go +++ b/x-pack/elastic-agent/pkg/artifact/download/http/elastic_test.go @@ -18,17 +18,24 @@ import ( "testing" "time" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" ) const ( - beatName = "filebeat" - artifactName = "beats/filebeat" version = "7.5.1" sourcePattern = "/downloads/beats/filebeat/" source = "http://artifacts.elastic.co/downloads/" ) +var ( + beatSpec = program.Spec{ + Name: "Filebeat", + Cmd: "filebeat", + Artifact: "beats/filebeat", + } +) + type testCase struct { system string arch string @@ -57,7 +64,7 @@ func TestDownload(t *testing.T) { config.Architecture = testCase.arch testClient := NewDownloaderWithClient(config, elasticClient) - artifactPath, err := testClient.Download(context.Background(), beatName, artifactName, version) + artifactPath, err := testClient.Download(context.Background(), beatSpec, version) if err != nil { t.Fatal(err) } @@ -95,7 +102,7 @@ func TestVerify(t *testing.T) { config.Architecture = testCase.arch testClient := NewDownloaderWithClient(config, elasticClient) - artifact, err := testClient.Download(context.Background(), beatName, artifactName, version) + artifact, err := testClient.Download(context.Background(), beatSpec, version) if err != nil { t.Fatal(err) } @@ -110,7 +117,7 @@ func TestVerify(t *testing.T) { t.Fatal(err) } - isOk, err := testVerifier.Verify(beatName, version, artifactName, false) + isOk, err := testVerifier.Verify(beatSpec, version, false) if err != nil { t.Fatal(err) } @@ -152,15 +159,15 @@ func getRandomTestCases() []testCase { func getElasticCoClient() http.Client { correctValues := map[string]struct{}{ - fmt.Sprintf("%s-%s-%s", beatName, version, "i386.deb"): struct{}{}, - fmt.Sprintf("%s-%s-%s", beatName, version, "amd64.deb"): struct{}{}, - fmt.Sprintf("%s-%s-%s", beatName, version, "i686.rpm"): struct{}{}, - fmt.Sprintf("%s-%s-%s", beatName, version, "x86_64.rpm"): struct{}{}, - fmt.Sprintf("%s-%s-%s", beatName, version, "linux-x86.tar.gz"): struct{}{}, - fmt.Sprintf("%s-%s-%s", beatName, version, "linux-x86_64.tar.gz"): struct{}{}, - fmt.Sprintf("%s-%s-%s", beatName, version, "windows-x86.zip"): struct{}{}, - fmt.Sprintf("%s-%s-%s", beatName, version, "windows-x86_64.zip"): struct{}{}, - fmt.Sprintf("%s-%s-%s", beatName, version, "darwin-x86_64.tar.gz"): struct{}{}, + fmt.Sprintf("%s-%s-%s", beatSpec.Cmd, version, "i386.deb"): struct{}{}, + fmt.Sprintf("%s-%s-%s", beatSpec.Cmd, version, "amd64.deb"): struct{}{}, + fmt.Sprintf("%s-%s-%s", beatSpec.Cmd, version, "i686.rpm"): struct{}{}, + fmt.Sprintf("%s-%s-%s", beatSpec.Cmd, version, "x86_64.rpm"): struct{}{}, + fmt.Sprintf("%s-%s-%s", beatSpec.Cmd, version, "linux-x86.tar.gz"): struct{}{}, + fmt.Sprintf("%s-%s-%s", beatSpec.Cmd, version, "linux-x86_64.tar.gz"): struct{}{}, + fmt.Sprintf("%s-%s-%s", beatSpec.Cmd, version, "windows-x86.zip"): struct{}{}, + fmt.Sprintf("%s-%s-%s", beatSpec.Cmd, version, "windows-x86_64.zip"): struct{}{}, + fmt.Sprintf("%s-%s-%s", beatSpec.Cmd, version, "darwin-x86_64.tar.gz"): struct{}{}, } handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/x-pack/elastic-agent/pkg/artifact/download/http/verifier.go b/x-pack/elastic-agent/pkg/artifact/download/http/verifier.go index da5b6b7d550..b206bd5faea 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/http/verifier.go +++ b/x-pack/elastic-agent/pkg/artifact/download/http/verifier.go @@ -20,6 +20,7 @@ import ( "golang.org/x/crypto/openpgp" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" ) @@ -60,13 +61,13 @@ func NewVerifier(config *artifact.Config, allowEmptyPgp bool, pgp []byte) (*Veri // Verify checks downloaded package on preconfigured // location agains a key stored on elastic.co website. -func (v *Verifier) Verify(programName, version, artifactName string, removeOnFailure bool) (isMatch bool, err error) { - filename, err := artifact.GetArtifactName(programName, version, v.config.OS(), v.config.Arch()) +func (v *Verifier) Verify(spec program.Spec, version string, removeOnFailure bool) (isMatch bool, err error) { + filename, err := artifact.GetArtifactName(spec, version, v.config.OS(), v.config.Arch()) if err != nil { return false, errors.New(err, "retrieving package name") } - fullPath, err := artifact.GetArtifactPath(programName, version, v.config.OS(), v.config.Arch(), v.config.TargetDirectory) + fullPath, err := artifact.GetArtifactPath(spec, version, v.config.OS(), v.config.Arch(), v.config.TargetDirectory) if err != nil { return false, errors.New(err, "retrieving package path") } @@ -84,7 +85,7 @@ func (v *Verifier) Verify(programName, version, artifactName string, removeOnFai return isMatch, err } - return v.verifyAsc(programName, version, artifactName) + return v.verifyAsc(spec, version) } func (v *Verifier) verifyHash(filename, fullPath string) (bool, error) { @@ -132,23 +133,23 @@ func (v *Verifier) verifyHash(filename, fullPath string) (bool, error) { return expectedHash == computedHash, nil } -func (v *Verifier) verifyAsc(programName, version, artifactName string) (bool, error) { +func (v *Verifier) verifyAsc(spec program.Spec, version string) (bool, error) { if len(v.pgpBytes) == 0 { // no pgp available skip verification process return true, nil } - filename, err := artifact.GetArtifactName(programName, version, v.config.OS(), v.config.Arch()) + filename, err := artifact.GetArtifactName(spec, version, v.config.OS(), v.config.Arch()) if err != nil { return false, errors.New(err, "retrieving package name") } - fullPath, err := artifact.GetArtifactPath(programName, version, v.config.OS(), v.config.Arch(), v.config.TargetDirectory) + fullPath, err := artifact.GetArtifactPath(spec, version, v.config.OS(), v.config.Arch(), v.config.TargetDirectory) if err != nil { return false, errors.New(err, "retrieving package path") } - ascURI, err := v.composeURI(filename, artifactName) + ascURI, err := v.composeURI(filename, spec.Artifact) if err != nil { return false, errors.New(err, "composing URI for fetching asc file", errors.TypeNetwork) } diff --git a/x-pack/elastic-agent/pkg/artifact/download/verifier.go b/x-pack/elastic-agent/pkg/artifact/download/verifier.go index d7b2bc7a415..7a8bbfced02 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/verifier.go +++ b/x-pack/elastic-agent/pkg/artifact/download/verifier.go @@ -4,7 +4,9 @@ package download +import "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" + // Verifier is an interface verifying GPG key of a downloaded artifact type Verifier interface { - Verify(programName, version, artifactName string, removeOnFailure bool) (bool, error) + Verify(spec program.Spec, version string, removeOnFailure bool) (bool, error) } diff --git a/x-pack/elastic-agent/pkg/artifact/install/atomic/atomic_installer.go b/x-pack/elastic-agent/pkg/artifact/install/atomic/atomic_installer.go index 3dc0dbe232a..f6c139ca463 100644 --- a/x-pack/elastic-agent/pkg/artifact/install/atomic/atomic_installer.go +++ b/x-pack/elastic-agent/pkg/artifact/install/atomic/atomic_installer.go @@ -11,10 +11,11 @@ import ( "path/filepath" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" ) type embeddedInstaller interface { - Install(ctx context.Context, programName, version, installDir string) error + Install(ctx context.Context, spec program.Spec, version, installDir string) error } // Installer installs into temporary destination and moves to correct one after @@ -31,7 +32,7 @@ func NewInstaller(i embeddedInstaller) (*Installer, error) { } // Install performs installation of program in a specific version. -func (i *Installer) Install(ctx context.Context, programName, version, installDir string) error { +func (i *Installer) Install(ctx context.Context, spec program.Spec, version, installDir string) error { // tar installer uses Dir of installDir to determine location of unpack tempDir, err := ioutil.TempDir(paths.TempDir(), "elastic-agent-install") if err != nil { @@ -48,7 +49,7 @@ func (i *Installer) Install(ctx context.Context, programName, version, installDi os.RemoveAll(tempInstallDir) } - if err := i.installer.Install(ctx, programName, version, tempInstallDir); err != nil { + if err := i.installer.Install(ctx, spec, version, tempInstallDir); err != nil { // cleanup unfinished install os.RemoveAll(tempInstallDir) return err diff --git a/x-pack/elastic-agent/pkg/artifact/install/atomic/atomic_installer_test.go b/x-pack/elastic-agent/pkg/artifact/install/atomic/atomic_installer_test.go index a0bfa213ca7..dce6ec72565 100644 --- a/x-pack/elastic-agent/pkg/artifact/install/atomic/atomic_installer_test.go +++ b/x-pack/elastic-agent/pkg/artifact/install/atomic/atomic_installer_test.go @@ -16,6 +16,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" ) func TestOKInstall(t *testing.T) { @@ -23,6 +24,7 @@ func TestOKInstall(t *testing.T) { ti := &testInstaller{sig} var wg sync.WaitGroup i, err := NewInstaller(ti) + s := program.Spec{Name: "a", Cmd: "a"} assert.NoError(t, err) @@ -31,7 +33,7 @@ func TestOKInstall(t *testing.T) { wg.Add(1) go func() { - err := i.Install(ctx, "a", "b", installDir) + err := i.Install(ctx, s, "b", installDir) assert.NoError(t, err) wg.Done() }() @@ -57,6 +59,7 @@ func TestContextCancelledInstall(t *testing.T) { ti := &testInstaller{sig} var wg sync.WaitGroup i, err := NewInstaller(ti) + s := program.Spec{Name: "a", Cmd: "a"} assert.NoError(t, err) @@ -65,7 +68,7 @@ func TestContextCancelledInstall(t *testing.T) { wg.Add(1) go func() { - err := i.Install(ctx, "a", "b", installDir) + err := i.Install(ctx, s, "b", installDir) assert.Error(t, err) wg.Done() }() @@ -83,7 +86,7 @@ type testInstaller struct { signal chan int } -func (ti *testInstaller) Install(ctx context.Context, programName, version, installDir string) error { +func (ti *testInstaller) Install(ctx context.Context, _ program.Spec, _, installDir string) error { files := getFiles() if err := os.MkdirAll(installDir, 0777); err != nil { return err diff --git a/x-pack/elastic-agent/pkg/artifact/install/dir/dir_checker.go b/x-pack/elastic-agent/pkg/artifact/install/dir/dir_checker.go index 56ecffdc5c0..40e1646e65e 100644 --- a/x-pack/elastic-agent/pkg/artifact/install/dir/dir_checker.go +++ b/x-pack/elastic-agent/pkg/artifact/install/dir/dir_checker.go @@ -7,6 +7,8 @@ package dir import ( "context" "os" + + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" ) // Checker performs basic check that the install directory exists. @@ -18,7 +20,7 @@ func NewChecker() *Checker { } // Check checks that the install directory exists. -func (*Checker) Check(_ context.Context, _, _, installDir string) error { +func (*Checker) Check(_ context.Context, _ program.Spec, _, installDir string) error { _, err := os.Stat(installDir) return err } diff --git a/x-pack/elastic-agent/pkg/artifact/install/hooks/hooks_installer.go b/x-pack/elastic-agent/pkg/artifact/install/hooks/hooks_installer.go index 8df01fdae7a..bb7683e3a5d 100644 --- a/x-pack/elastic-agent/pkg/artifact/install/hooks/hooks_installer.go +++ b/x-pack/elastic-agent/pkg/artifact/install/hooks/hooks_installer.go @@ -6,17 +6,16 @@ package hooks import ( "context" - "strings" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" ) type embeddedInstaller interface { - Install(ctx context.Context, programName, version, installDir string) error + Install(ctx context.Context, spec program.Spec, version, installDir string) error } type embeddedChecker interface { - Check(ctx context.Context, programName, version, installDir string) error + Check(ctx context.Context, spec program.Spec, version, installDir string) error } // InstallerChecker runs the PostInstallSteps after running the embedded installer @@ -36,16 +35,10 @@ func NewInstallerChecker(i embeddedInstaller, c embeddedChecker) (*InstallerChec // Install performs installation of program in a specific version, then runs the // PostInstallSteps for the program if defined. -func (i *InstallerChecker) Install(ctx context.Context, programName, version, installDir string) error { - if err := i.installer.Install(ctx, programName, version, installDir); err != nil { +func (i *InstallerChecker) Install(ctx context.Context, spec program.Spec, version, installDir string) error { + if err := i.installer.Install(ctx, spec, version, installDir); err != nil { return err } - - // post install hooks - spec, ok := program.SupportedMap[strings.ToLower(programName)] - if !ok { - return nil - } if spec.PostInstallSteps != nil { return spec.PostInstallSteps.Execute(ctx, installDir) } @@ -54,17 +47,11 @@ func (i *InstallerChecker) Install(ctx context.Context, programName, version, in // Check performs installation check of program to ensure that it is already installed, then // runs the InstallerCheckSteps to ensure that the installation is valid. -func (i *InstallerChecker) Check(ctx context.Context, programName, version, installDir string) error { - err := i.checker.Check(ctx, programName, version, installDir) +func (i *InstallerChecker) Check(ctx context.Context, spec program.Spec, version, installDir string) error { + err := i.checker.Check(ctx, spec, version, installDir) if err != nil { return err } - - // installer check steps - spec, ok := program.SupportedMap[strings.ToLower(programName)] - if !ok { - return nil - } if spec.CheckInstallSteps != nil { return spec.CheckInstallSteps.Execute(ctx, installDir) } diff --git a/x-pack/elastic-agent/pkg/artifact/install/installer.go b/x-pack/elastic-agent/pkg/artifact/install/installer.go index c606ada5d65..b99563ff997 100644 --- a/x-pack/elastic-agent/pkg/artifact/install/installer.go +++ b/x-pack/elastic-agent/pkg/artifact/install/installer.go @@ -9,10 +9,10 @@ import ( "errors" "runtime" - "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/install/dir" - + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/install/atomic" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/install/dir" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/install/hooks" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/install/tar" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/install/zip" @@ -28,7 +28,7 @@ type Installer interface { // Install installs an artifact and returns // location of the installed program // error if something went wrong - Install(ctx context.Context, programName, version, installDir string) error + Install(ctx context.Context, spec program.Spec, version, installDir string) error } // InstallerChecker is an interface that installs but also checks for valid installation. @@ -36,7 +36,7 @@ type InstallerChecker interface { Installer // Check checks if the installation is good. - Check(ctx context.Context, programName, version, installDir string) error + Check(ctx context.Context, spec program.Spec, version, installDir string) error } // NewInstaller returns a correct installer associated with a diff --git a/x-pack/elastic-agent/pkg/artifact/install/tar/tar_installer.go b/x-pack/elastic-agent/pkg/artifact/install/tar/tar_installer.go index 74a74e4c6bc..2452f5909cc 100644 --- a/x-pack/elastic-agent/pkg/artifact/install/tar/tar_installer.go +++ b/x-pack/elastic-agent/pkg/artifact/install/tar/tar_installer.go @@ -15,6 +15,7 @@ import ( "strings" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" ) @@ -32,15 +33,15 @@ func NewInstaller(config *artifact.Config) (*Installer, error) { // Install performs installation of program in a specific version. // It expects package to be already downloaded. -func (i *Installer) Install(_ context.Context, programName, version, installDir string) error { - artifactPath, err := artifact.GetArtifactPath(programName, version, i.config.OS(), i.config.Arch(), i.config.TargetDirectory) +func (i *Installer) Install(_ context.Context, spec program.Spec, version, installDir string) error { + artifactPath, err := artifact.GetArtifactPath(spec, version, i.config.OS(), i.config.Arch(), i.config.TargetDirectory) if err != nil { return err } f, err := os.Open(artifactPath) if err != nil { - return errors.New(fmt.Sprintf("artifact for '%s' version '%s' could not be found at '%s'", programName, version, artifactPath), errors.TypeFilesystem, errors.M(errors.MetaKeyPath, artifactPath)) + return errors.New(fmt.Sprintf("artifact for '%s' version '%s' could not be found at '%s'", spec.Name, version, artifactPath), errors.TypeFilesystem, errors.M(errors.MetaKeyPath, artifactPath)) } defer f.Close() diff --git a/x-pack/elastic-agent/pkg/artifact/install/zip/zip_installer.go b/x-pack/elastic-agent/pkg/artifact/install/zip/zip_installer.go index b565f630a73..fdd374eb72a 100644 --- a/x-pack/elastic-agent/pkg/artifact/install/zip/zip_installer.go +++ b/x-pack/elastic-agent/pkg/artifact/install/zip/zip_installer.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/go-multierror" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" ) @@ -36,8 +37,8 @@ func NewInstaller(config *artifact.Config) (*Installer, error) { // Install performs installation of program in a specific version. // It expects package to be already downloaded. -func (i *Installer) Install(_ context.Context, programName, version, installDir string) error { - artifactPath, err := artifact.GetArtifactPath(programName, version, i.config.OS(), i.config.Arch(), i.config.TargetDirectory) +func (i *Installer) Install(_ context.Context, spec program.Spec, version, installDir string) error { + artifactPath, err := artifact.GetArtifactPath(spec, version, i.config.OS(), i.config.Arch(), i.config.TargetDirectory) if err != nil { return err } diff --git a/x-pack/elastic-agent/pkg/artifact/uninstall/hooks/hooks_uninstaller.go b/x-pack/elastic-agent/pkg/artifact/uninstall/hooks/hooks_uninstaller.go index 250c703be66..2d75d6053cc 100644 --- a/x-pack/elastic-agent/pkg/artifact/uninstall/hooks/hooks_uninstaller.go +++ b/x-pack/elastic-agent/pkg/artifact/uninstall/hooks/hooks_uninstaller.go @@ -6,13 +6,12 @@ package hooks import ( "context" - "strings" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" ) type embeddedUninstaller interface { - Uninstall(ctx context.Context, programName, version, installDir string) error + Uninstall(ctx context.Context, spec program.Spec, version, installDir string) error } // Uninstaller that executes PreUninstallSteps @@ -28,14 +27,9 @@ func NewUninstaller(i embeddedUninstaller) (*Uninstaller, error) { } // Uninstall performs the execution of the PreUninstallSteps -func (i *Uninstaller) Uninstall(ctx context.Context, programName, version, installDir string) error { - // pre uninstall hooks - spec, ok := program.SupportedMap[strings.ToLower(programName)] - if !ok { - return nil - } +func (i *Uninstaller) Uninstall(ctx context.Context, spec program.Spec, version, installDir string) error { if spec.PreUninstallSteps != nil { return spec.PreUninstallSteps.Execute(ctx, installDir) } - return i.uninstaller.Uninstall(ctx, programName, version, installDir) + return i.uninstaller.Uninstall(ctx, spec, version, installDir) } diff --git a/x-pack/elastic-agent/pkg/artifact/uninstall/uninstaller.go b/x-pack/elastic-agent/pkg/artifact/uninstall/uninstaller.go index f2965f8dcf4..8cb3620c234 100644 --- a/x-pack/elastic-agent/pkg/artifact/uninstall/uninstaller.go +++ b/x-pack/elastic-agent/pkg/artifact/uninstall/uninstaller.go @@ -7,13 +7,14 @@ package uninstall import ( "context" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/uninstall/hooks" ) // Uninstaller is an interface allowing un-installation of an artifact type Uninstaller interface { // Uninstall uninstalls an artifact. - Uninstall(ctx context.Context, programName, version, installDir string) error + Uninstall(ctx context.Context, spec program.Spec, version, installDir string) error } // NewUninstaller returns a correct uninstaller. @@ -23,6 +24,6 @@ func NewUninstaller() (Uninstaller, error) { type nilUninstaller struct{} -func (*nilUninstaller) Uninstall(_ context.Context, _, _, _ string) error { +func (*nilUninstaller) Uninstall(_ context.Context, _ program.Spec, _, _ string) error { return nil } diff --git a/x-pack/elastic-agent/pkg/core/app/descriptor.go b/x-pack/elastic-agent/pkg/core/app/descriptor.go index 330b0da11e7..a5445e6178d 100644 --- a/x-pack/elastic-agent/pkg/core/app/descriptor.go +++ b/x-pack/elastic-agent/pkg/core/app/descriptor.go @@ -16,22 +16,20 @@ import ( // Descriptor defines a program which needs to be run. // Is passed around operator operations. type Descriptor struct { - artifactName string + spec program.Spec executionCtx ExecutionContext directory string - spec ProcessSpec + process ProcessSpec } // NewDescriptor creates a program which satisfies Program interface and can be used with Operator. -func NewDescriptor(pSpec program.Spec, version string, config *artifact.Config, tags map[Tag]string) *Descriptor { - binaryName := strings.ToLower(pSpec.Cmd) - dir := directory(binaryName, version, config) - +func NewDescriptor(spec program.Spec, version string, config *artifact.Config, tags map[Tag]string) *Descriptor { + dir := directory(spec, version, config) return &Descriptor{ - artifactName: pSpec.Artifact, + spec: spec, directory: dir, - executionCtx: NewExecutionContext(pSpec.ServicePort, binaryName, version, tags), - spec: spec(dir, binaryName), + executionCtx: NewExecutionContext(spec.ServicePort, spec.Cmd, version, tags), + process: specification(dir, spec.Cmd), } } @@ -43,7 +41,7 @@ func (p *Descriptor) ServicePort() int { // ArtifactName is the name of the artifact to download from the artifact store. E.g beats/filebeat. func (p *Descriptor) ArtifactName() string { - return p.artifactName + return p.spec.Artifact } // BinaryName is the name of the binary. E.g filebeat. @@ -65,11 +63,16 @@ func (p *Descriptor) ID() string { return p.executionCtx.ID } // ExecutionContext returns execution context of the application. func (p *Descriptor) ExecutionContext() ExecutionContext { return p.executionCtx } -// Spec returns a Process Specification with resolved binary path. -func (p *Descriptor) Spec() ProcessSpec { +// Spec returns a program specification with resolved binary path. +func (p *Descriptor) Spec() program.Spec { return p.spec } +// ProcessSpec returns a process specification with resolved binary path. +func (p *Descriptor) ProcessSpec() ProcessSpec { + return p.process +} + // Directory specifies the root directory of the application within an install path. func (p *Descriptor) Directory() string { return p.directory @@ -89,17 +92,17 @@ func defaultSpec(dir string, binaryName string) ProcessSpec { } -func spec(directory, binaryName string) ProcessSpec { +func specification(directory, binaryName string) ProcessSpec { defaultSpec := defaultSpec(directory, binaryName) return populateSpec(directory, binaryName, defaultSpec) } -func directory(binaryName, version string, config *artifact.Config) string { +func directory(spec program.Spec, version string, config *artifact.Config) string { if version == "" { - return filepath.Join(config.InstallPath, binaryName) + return filepath.Join(config.InstallPath, spec.Cmd) } - path, err := artifact.GetArtifactPath(binaryName, version, config.OS(), config.Arch(), config.InstallPath) + path, err := artifact.GetArtifactPath(spec, version, config.OS(), config.Arch(), config.InstallPath) if err != nil { return "" } diff --git a/x-pack/elastic-agent/pkg/core/app/spec.go b/x-pack/elastic-agent/pkg/core/app/spec.go index 3da422e2930..6f09c52e34b 100644 --- a/x-pack/elastic-agent/pkg/core/app/spec.go +++ b/x-pack/elastic-agent/pkg/core/app/spec.go @@ -8,11 +8,6 @@ import ( "os/user" ) -// Specifier returns a process specification. -type Specifier interface { - Spec() ProcessSpec -} - // ProcessSpec specifies a way of running a process type ProcessSpec struct { // Binary path. diff --git a/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go b/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go index 2b4617bc2bd..b7cf0a3d976 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/beats/beats_monitor.go @@ -14,6 +14,7 @@ import ( "unicode" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/configuration" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/config" monitoringConfig "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/monitoring/config" @@ -74,25 +75,25 @@ func (b *Monitor) WatchLogs() bool { return b.config.Enabled && b.config.Monitor // WatchMetrics returns true if monitoring is enabled and monitor should watch metrics. func (b *Monitor) WatchMetrics() bool { return b.config.Enabled && b.config.MonitorMetrics } -func (b *Monitor) generateMonitoringEndpoint(process, pipelineID string) string { - return getMonitoringEndpoint(process, b.operatingSystem, pipelineID) +func (b *Monitor) generateMonitoringEndpoint(spec program.Spec, pipelineID string) string { + return getMonitoringEndpoint(spec, b.operatingSystem, pipelineID) } -func (b *Monitor) generateLoggingFile(process, pipelineID string) string { - return getLoggingFile(process, b.operatingSystem, b.installPath, pipelineID) +func (b *Monitor) generateLoggingFile(spec program.Spec, pipelineID string) string { + return getLoggingFile(spec, b.operatingSystem, b.installPath, pipelineID) } -func (b *Monitor) generateLoggingPath(process, pipelineID string) string { - return filepath.Dir(b.generateLoggingFile(process, pipelineID)) +func (b *Monitor) generateLoggingPath(spec program.Spec, pipelineID string) string { + return filepath.Dir(b.generateLoggingFile(spec, pipelineID)) } // EnrichArgs enriches arguments provided to application, in order to enable // monitoring -func (b *Monitor) EnrichArgs(process, pipelineID string, args []string, isSidecar bool) []string { +func (b *Monitor) EnrichArgs(spec program.Spec, pipelineID string, args []string, isSidecar bool) []string { appendix := make([]string, 0, 7) - monitoringEndpoint := b.generateMonitoringEndpoint(process, pipelineID) + monitoringEndpoint := b.generateMonitoringEndpoint(spec, pipelineID) if monitoringEndpoint != "" { endpoint := monitoringEndpoint if isSidecar { @@ -104,9 +105,9 @@ func (b *Monitor) EnrichArgs(process, pipelineID string, args []string, isSideca ) } - loggingPath := b.generateLoggingPath(process, pipelineID) + loggingPath := b.generateLoggingPath(spec, pipelineID) if loggingPath != "" { - logFile := process + logFile := spec.Cmd if isSidecar { logFile += "_monitor" } @@ -125,9 +126,9 @@ func (b *Monitor) EnrichArgs(process, pipelineID string, args []string, isSideca } // Cleanup removes -func (b *Monitor) Cleanup(process, pipelineID string) error { +func (b *Monitor) Cleanup(spec program.Spec, pipelineID string) error { // do not cleanup logs, they might not be all processed - drop := b.monitoringDrop(process, pipelineID) + drop := b.monitoringDrop(spec, pipelineID) if drop == "" { return nil } @@ -136,9 +137,9 @@ func (b *Monitor) Cleanup(process, pipelineID string) error { } // Prepare executes steps in order for monitoring to work correctly -func (b *Monitor) Prepare(process, pipelineID string, uid, gid int) error { - drops := []string{b.generateLoggingPath(process, pipelineID)} - if drop := b.monitoringDrop(process, pipelineID); drop != "" { +func (b *Monitor) Prepare(spec program.Spec, pipelineID string, uid, gid int) error { + drops := []string{b.generateLoggingPath(spec, pipelineID)} + if drop := b.monitoringDrop(spec, pipelineID); drop != "" { drops = append(drops, drop) } @@ -169,31 +170,31 @@ func (b *Monitor) Prepare(process, pipelineID string, uid, gid int) error { // LogPath describes a path where application stores logs. Empty if // application is not monitorable -func (b *Monitor) LogPath(process, pipelineID string) string { +func (b *Monitor) LogPath(spec program.Spec, pipelineID string) string { if !b.WatchLogs() { return "" } - return b.generateLoggingFile(process, pipelineID) + return b.generateLoggingFile(spec, pipelineID) } // MetricsPath describes a location where application exposes metrics // collectable by metricbeat. -func (b *Monitor) MetricsPath(process, pipelineID string) string { +func (b *Monitor) MetricsPath(spec program.Spec, pipelineID string) string { if !b.WatchMetrics() { return "" } - return b.generateMonitoringEndpoint(process, pipelineID) + return b.generateMonitoringEndpoint(spec, pipelineID) } // MetricsPathPrefixed return metrics path prefixed with http+ prefix. -func (b *Monitor) MetricsPathPrefixed(process, pipelineID string) string { - return httpPlusPrefix + b.MetricsPath(process, pipelineID) +func (b *Monitor) MetricsPathPrefixed(spec program.Spec, pipelineID string) string { + return httpPlusPrefix + b.MetricsPath(spec, pipelineID) } -func (b *Monitor) monitoringDrop(process, pipelineID string) string { - return monitoringDrop(b.generateMonitoringEndpoint(process, pipelineID)) +func (b *Monitor) monitoringDrop(spec program.Spec, pipelineID string) string { + return monitoringDrop(b.generateMonitoringEndpoint(spec, pipelineID)) } func monitoringDrop(path string) (drop string) { diff --git a/x-pack/elastic-agent/pkg/core/monitoring/beats/monitoring.go b/x-pack/elastic-agent/pkg/core/monitoring/beats/monitoring.go index f75108425a0..203a101fd83 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/beats/monitoring.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/beats/monitoring.go @@ -8,6 +8,7 @@ import ( "fmt" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" ) const ( @@ -22,18 +23,22 @@ const ( mbEndpointFileFormatWin = `npipe:///%s-%s` ) -func getMonitoringEndpoint(program, operatingSystem, pipelineID string) string { +func getMonitoringEndpoint(spec program.Spec, operatingSystem, pipelineID string) string { + if endpoint, ok := spec.MetricEndpoints[operatingSystem]; ok { + return endpoint + } if operatingSystem == "windows" { - return fmt.Sprintf(mbEndpointFileFormatWin, pipelineID, program) + return fmt.Sprintf(mbEndpointFileFormatWin, pipelineID, spec.Cmd) } - - return fmt.Sprintf(mbEndpointFileFormat, pipelineID, program, program) + return fmt.Sprintf(mbEndpointFileFormat, pipelineID, spec.Cmd, spec.Cmd) } -func getLoggingFile(program, operatingSystem, installPath, pipelineID string) string { +func getLoggingFile(spec program.Spec, operatingSystem, installPath, pipelineID string) string { + if path, ok := spec.LogPaths[operatingSystem]; ok { + return path + } if operatingSystem == "windows" { - return fmt.Sprintf(logFileFormatWin, paths.Home(), pipelineID, program) + return fmt.Sprintf(logFileFormatWin, paths.Home(), pipelineID, spec.Cmd) } - - return fmt.Sprintf(logFileFormat, paths.Home(), pipelineID, program) + return fmt.Sprintf(logFileFormat, paths.Home(), pipelineID, spec.Cmd) } diff --git a/x-pack/elastic-agent/pkg/core/monitoring/monitor.go b/x-pack/elastic-agent/pkg/core/monitoring/monitor.go index 0930e407187..61ebdf3c771 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/monitor.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/monitor.go @@ -6,6 +6,7 @@ package monitoring import ( "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/configuration" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/config" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/monitoring/beats" @@ -15,13 +16,13 @@ import ( // Monitor is a monitoring interface providing information about the way // how application is monitored type Monitor interface { - LogPath(process, pipelineID string) string - MetricsPath(process, pipelineID string) string - MetricsPathPrefixed(process, pipelineID string) string + LogPath(spec program.Spec, pipelineID string) string + MetricsPath(spec program.Spec, pipelineID string) string + MetricsPathPrefixed(spec program.Spec, pipelineID string) string - Prepare(process, pipelineID string, uid, gid int) error - EnrichArgs(string, string, []string, bool) []string - Cleanup(process, pipelineID string) error + Prepare(spec program.Spec, pipelineID string, uid, gid int) error + EnrichArgs(spec program.Spec, pipelineID string, args []string, isSidecar bool) []string + Cleanup(spec program.Spec, pipelineID string) error Reload(cfg *config.Config) error IsMonitoringEnabled() bool WatchLogs() bool diff --git a/x-pack/elastic-agent/pkg/core/monitoring/noop/noop_monitor.go b/x-pack/elastic-agent/pkg/core/monitoring/noop/noop_monitor.go index ae573d591b9..9ea8f08a788 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/noop/noop_monitor.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/noop/noop_monitor.go @@ -4,7 +4,10 @@ package noop -import "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/config" +import ( + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/config" +) // Monitor is a monitoring interface providing information about the way // how beat is monitored @@ -18,12 +21,12 @@ func NewMonitor() *Monitor { // EnrichArgs enriches arguments provided to application, in order to enable // monitoring -func (b *Monitor) EnrichArgs(_ string, _ string, args []string, _ bool) []string { +func (b *Monitor) EnrichArgs(_ program.Spec, _ string, args []string, _ bool) []string { return args } // Cleanup cleans up all drops. -func (b *Monitor) Cleanup(string, string) error { +func (b *Monitor) Cleanup(program.Spec, string) error { return nil } @@ -31,24 +34,24 @@ func (b *Monitor) Cleanup(string, string) error { func (b *Monitor) Close() {} // Prepare executes steps in order for monitoring to work correctly -func (b *Monitor) Prepare(string, string, int, int) error { +func (b *Monitor) Prepare(program.Spec, string, int, int) error { return nil } // LogPath describes a path where application stores logs. Empty if // application is not monitorable -func (b *Monitor) LogPath(string, string) string { +func (b *Monitor) LogPath(program.Spec, string) string { return "" } // MetricsPath describes a location where application exposes metrics // collectable by metricbeat. -func (b *Monitor) MetricsPath(string, string) string { +func (b *Monitor) MetricsPath(program.Spec, string) string { return "" } // MetricsPathPrefixed return metrics path prefixed with http+ prefix. -func (b *Monitor) MetricsPathPrefixed(string, string) string { +func (b *Monitor) MetricsPathPrefixed(program.Spec, string) string { return "" } diff --git a/x-pack/elastic-agent/pkg/core/plugin/process/app.go b/x-pack/elastic-agent/pkg/core/plugin/process/app.go index 8732af24f68..d991c8f0b80 100644 --- a/x-pack/elastic-agent/pkg/core/plugin/process/app.go +++ b/x-pack/elastic-agent/pkg/core/plugin/process/app.go @@ -16,6 +16,7 @@ import ( "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/configuration" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/app" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/logger" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/monitoring" @@ -37,7 +38,7 @@ type Application struct { name string pipelineID string logLevel string - spec app.Specifier + desc *app.Descriptor srv *server.Server srvState *server.ApplicationState limiter *tokenbucket.Bucket @@ -66,14 +67,14 @@ type ArgsDecorator func([]string) []string func NewApplication( ctx context.Context, id, appName, pipelineID, logLevel string, - spec app.Specifier, + desc *app.Descriptor, srv *server.Server, cfg *configuration.SettingsConfig, logger *logger.Logger, reporter state.Reporter, monitor monitoring.Monitor) (*Application, error) { - s := spec.Spec() + s := desc.ProcessSpec() uid, gid, err := s.UserGroup() if err != nil { return nil, err @@ -86,7 +87,7 @@ func NewApplication( name: appName, pipelineID: pipelineID, logLevel: logLevel, - spec: spec, + desc: desc, srv: srv, processConfig: cfg.ProcessConfig, logger: logger, @@ -103,6 +104,11 @@ func (a *Application) Monitor() monitoring.Monitor { return a.monitor } +// Spec returns the program spec of this app. +func (a *Application) Spec() program.Spec { + return a.desc.Spec() +} + // State returns the application state. func (a *Application) State() state.State { a.appLock.Lock() @@ -252,5 +258,5 @@ func (a *Application) setState(status state.Status, msg string, payload map[stri } func (a *Application) cleanUp() { - a.monitor.Cleanup(a.name, a.pipelineID) + a.monitor.Cleanup(a.desc.Spec(), a.pipelineID) } diff --git a/x-pack/elastic-agent/pkg/core/plugin/process/start.go b/x-pack/elastic-agent/pkg/core/plugin/process/start.go index bc19910e53c..915cbe155ff 100644 --- a/x-pack/elastic-agent/pkg/core/plugin/process/start.go +++ b/x-pack/elastic-agent/pkg/core/plugin/process/start.go @@ -84,7 +84,7 @@ func (a *Application) start(ctx context.Context, t app.Taggable, cfg map[string] } }() - if err := a.monitor.Prepare(a.name, a.pipelineID, a.uid, a.gid); err != nil { + if err := a.monitor.Prepare(a.desc.Spec(), a.pipelineID, a.uid, a.gid); err != nil { return err } @@ -92,12 +92,12 @@ func (a *Application) start(ctx context.Context, t app.Taggable, cfg map[string] a.limiter.Add() } - spec := a.spec.Spec() + spec := a.desc.ProcessSpec() spec.Args = injectLogLevel(a.logLevel, spec.Args) // use separate file isSidecar := app.IsSidecar(t) - spec.Args = a.monitor.EnrichArgs(a.name, a.pipelineID, spec.Args, isSidecar) + spec.Args = a.monitor.EnrichArgs(a.desc.Spec(), a.pipelineID, spec.Args, isSidecar) // specify beat name to avoid data lock conflicts // as for https://github.com/elastic/beats/v7/pull/14030 more than one instance diff --git a/x-pack/elastic-agent/pkg/core/plugin/service/app.go b/x-pack/elastic-agent/pkg/core/plugin/service/app.go index d9e9fc681a2..653bc9cf87f 100644 --- a/x-pack/elastic-agent/pkg/core/plugin/service/app.go +++ b/x-pack/elastic-agent/pkg/core/plugin/service/app.go @@ -13,6 +13,8 @@ import ( "sync" "time" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" + "gopkg.in/yaml.v2" "github.com/elastic/elastic-agent-client/v7/pkg/proto" @@ -40,7 +42,7 @@ type Application struct { name string pipelineID string logLevel string - spec app.Specifier + desc *app.Descriptor srv *server.Server srvState *server.ApplicationState limiter *tokenbucket.Bucket @@ -70,14 +72,14 @@ func NewApplication( ctx context.Context, id, appName, pipelineID, logLevel string, credsPort int, - spec app.Specifier, + desc *app.Descriptor, srv *server.Server, cfg *configuration.SettingsConfig, logger *logger.Logger, reporter state.Reporter, monitor monitoring.Monitor) (*Application, error) { - s := spec.Spec() + s := desc.ProcessSpec() uid, gid, err := s.UserGroup() if err != nil { return nil, err @@ -90,7 +92,7 @@ func NewApplication( name: appName, pipelineID: pipelineID, logLevel: logLevel, - spec: spec, + desc: desc, srv: srv, processConfig: cfg.ProcessConfig, logger: logger, @@ -108,6 +110,11 @@ func (a *Application) Monitor() monitoring.Monitor { return a.monitor } +// Spec returns the program spec of this app. +func (a *Application) Spec() program.Spec { + return a.desc.Spec() +} + // State returns the application state. func (a *Application) State() state.State { a.appLock.Lock() @@ -171,7 +178,7 @@ func (a *Application) Start(ctx context.Context, t app.Taggable, cfg map[string] } }() - if err := a.monitor.Prepare(a.name, a.pipelineID, a.uid, a.gid); err != nil { + if err := a.monitor.Prepare(a.desc.Spec(), a.pipelineID, a.uid, a.gid); err != nil { return err } @@ -307,7 +314,7 @@ func (a *Application) setState(status state.Status, msg string, payload map[stri } func (a *Application) cleanUp() { - a.monitor.Cleanup(a.name, a.pipelineID) + a.monitor.Cleanup(a.desc.Spec(), a.pipelineID) } func (a *Application) startCredsListener() error { diff --git a/x-pack/elastic-agent/spec/endpoint.yml b/x-pack/elastic-agent/spec/endpoint.yml index 75936c40477..1bc5817f5c1 100644 --- a/x-pack/elastic-agent/spec/endpoint.yml +++ b/x-pack/elastic-agent/spec/endpoint.yml @@ -2,6 +2,10 @@ name: Endpoint Security cmd: endpoint-security artifact: endpoint-dev service: 6788 +log_paths: + darwin: "/Library/Elastic/Endpoint/state/log/endpoint-*.log" + linux: "/opt/Elastic/Endpoint/state/log/endpoint-*.log" + windows: "C:\\Program Files\\Elastic\\Endpoint\\state\\log\\endpoint-*.log" check_install: - exec_file: path: "endpoint-security"