Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added skip audit/unenroll flag to uninstall command #6206

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions changelog/fragments/1733248787-flag-to-skip-fleet-audit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Kind can be one of:
# - breaking-change: a change to previously-documented behavior
# - deprecation: functionality that is being removed in a later release
# - bug-fix: fixes a problem in a previous version
# - enhancement: extends functionality but does not break or fix existing behavior
# - feature: new functionality
# - known-issue: problems that we are aware of in a given version
# - security: impacts on the security of a product or a user’s deployment.
# - upgrade: important information for someone upgrading from a prior version
# - other: does not fit into any of the other categories
kind: enhancement

# Change summary; a 80ish characters long description of the change.
summary: Add a flag to skip audit/unenroll call to fleet server during uninstall

# Long description; in case the summary is not enough to describe the change
# this field accommodate a description without length limits.
# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment.
description: This change adds a flag to skip audit/unenroll call to fleet server. While uninstalling elastic-agent it tries to notify fleet server about the uninstallation. But in somecases users might know that the fleet server is unreachable and this notification logs multiple failures continuously. Adding this flag skips this call.

# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc.
component: "elastic-agent"

# PR URL; optional; the PR number that added the changeset.
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
# Please provide it if you are adding a fragment for a different PR.
#pr: https://github.com/owner/repo/1234

# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
# If not present is automatically filled by the tooling with the issue linked to the PR number.
#issue: https://github.com/owner/repo/1234
4 changes: 2 additions & 2 deletions internal/pkg/agent/cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ func installCmd(streams *cli.IOStreams, cmd *cobra.Command) error {
return err
}
} else {
err := install.Uninstall(cmd.Context(), cfgFile, topPath, "", log, progBar)
err := install.Uninstall(cmd.Context(), cfgFile, topPath, "", log, progBar, false)
if err != nil {
progBar.Describe("Uninstall from binary failed")
return err
Expand All @@ -276,7 +276,7 @@ func installCmd(streams *cli.IOStreams, cmd *cobra.Command) error {
defer func() {
if err != nil {
progBar.Describe("Uninstalling")
innerErr := install.Uninstall(cmd.Context(), cfgFile, topPath, "", log, progBar)
innerErr := install.Uninstall(cmd.Context(), cfgFile, topPath, "", log, progBar, false)
if innerErr != nil {
progBar.Describe("Failed to Uninstall")
} else {
Expand Down
4 changes: 3 additions & 1 deletion internal/pkg/agent/cmd/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Unless -f is used this command will ask confirmation before performing removal.

cmd.Flags().BoolP("force", "f", false, "Force overwrite the current and do not prompt for confirmation")
cmd.Flags().String("uninstall-token", "", "Uninstall token required for protected agent uninstall")
cmd.Flags().Bool("skip-fleet-audit", false, "Skip fleet audit/unenroll")

return cmd
}
Expand All @@ -60,6 +61,7 @@ func uninstallCmd(streams *cli.IOStreams, cmd *cobra.Command) error {

force, _ := cmd.Flags().GetBool("force")
uninstallToken, _ := cmd.Flags().GetString("uninstall-token")
skipFleetAudit, _ := cmd.Flags().GetBool("skip-fleet-audit")
if status == install.Broken {
if !force {
fmt.Fprintf(streams.Out, "Elastic Agent is installed but currently broken: %s\n", reason)
Expand Down Expand Up @@ -94,7 +96,7 @@ func uninstallCmd(streams *cli.IOStreams, cmd *cobra.Command) error {
fmt.Fprint(os.Stderr, logBuff.String())
}()

err = install.Uninstall(cmd.Context(), paths.ConfigFile(), paths.Top(), uninstallToken, log, progBar)
err = install.Uninstall(cmd.Context(), paths.ConfigFile(), paths.Top(), uninstallToken, log, progBar, skipFleetAudit)
if err != nil {
progBar.Describe("Failed to uninstall agent")
return fmt.Errorf("error uninstalling agent: %w", err)
Expand Down
16 changes: 11 additions & 5 deletions internal/pkg/agent/install/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (a *agentInfo) AgentID() string {
}

// Uninstall uninstalls persistently Elastic Agent on the system.
func Uninstall(ctx context.Context, cfgFile, topPath, uninstallToken string, log *logp.Logger, pt *progressbar.ProgressBar) error {
func Uninstall(ctx context.Context, cfgFile, topPath, uninstallToken string, log *logp.Logger, pt *progressbar.ProgressBar, skipFleetAudit bool) error {
cwd, err := os.Getwd()
if err != nil {
return fmt.Errorf("unable to get current working directory")
Expand Down Expand Up @@ -166,13 +166,19 @@ func Uninstall(ctx context.Context, cfgFile, topPath, uninstallToken string, log
}
pt.Describe("Removed install directory")

if notifyFleet && !localFleet {
notifyFleetAuditUninstall(ctx, log, pt, cfg, &agentID) //nolint:errcheck // ignore the error as we can't act on it
}

notifyFleetIfNeeded(ctx, log, pt, cfg, agentID, notifyFleet, localFleet, skipFleetAudit, notifyFleetAuditUninstall)
return nil
}

// Injecting notifyFleetAuditUninstall for easier unit testing
func notifyFleetIfNeeded(ctx context.Context, log *logp.Logger, pt *progressbar.ProgressBar, cfg *configuration.Configuration, agentID agentInfo, notifyFleet, localFleet, skipFleetAudit bool, notifyFleetAuditUninstall NotifyFleetAuditUninstall) {
if notifyFleet && !localFleet && !skipFleetAudit {
notifyFleetAuditUninstall(ctx, log, pt, cfg, &agentID) //nolint:errcheck // ignore the error as we can't act on it)
}
}

type NotifyFleetAuditUninstall func(ctx context.Context, log *logp.Logger, pt *progressbar.ProgressBar, cfg *configuration.Configuration, ai fleetapi.AgentInfo) error

// notifyFleetAuditUninstall will attempt to notify fleet-server of the agent's uninstall.
//
// There are retries for the attempt after a 10s wait, but it is a best-effort approach.
Expand Down
20 changes: 20 additions & 0 deletions internal/pkg/agent/install/uninstall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/elastic/elastic-agent/internal/pkg/agent/application/secret"
"github.com/elastic/elastic-agent/internal/pkg/agent/configuration"
"github.com/elastic/elastic-agent/internal/pkg/agent/vault"
"github.com/elastic/elastic-agent/internal/pkg/fleetapi"
"github.com/elastic/elastic-agent/internal/pkg/fleetapi/client"
"github.com/elastic/elastic-agent/internal/pkg/remote"
)
Expand Down Expand Up @@ -226,3 +227,22 @@ func TestNotifyFleetAuditUnenroll(t *testing.T) {

})
}

type MockNotifyFleetAuditUninstall struct {
Called bool
}

func (m *MockNotifyFleetAuditUninstall) Call(ctx context.Context, log *logp.Logger, pt *progressbar.ProgressBar, cfg *configuration.Configuration, ai fleetapi.AgentInfo) {
m.Called = true
}

func TestSkipFleetAuditUnenroll(t *testing.T) {
log := &logp.Logger{}
pt := &progressbar.ProgressBar{}
cfg := &configuration.Configuration{}
var agentID agentInfo = "testID"

mockNotify := &MockNotifyFleetAuditUninstall{}
notifyFleetIfNeeded(context.Background(), log, pt, cfg, agentID, true, false, true, notifyFleetAuditUninstall)
Rohit-code14 marked this conversation as resolved.
Show resolved Hide resolved
assert.False(t, mockNotify.Called, "NotifyFleetAuditUninstall should not be called when skipFleetAudit is true")
}
Loading