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

remove flags for policy defaulting #30256

Closed
wants to merge 14 commits into from
1 change: 1 addition & 0 deletions x-pack/elastic-agent/CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,4 @@
- Discover changes in Kubernetes nodes metadata as soon as they happen. {pull}23139[23139]
- Add results of inspect output command into archive produced by diagnostics collect. {pull}29902[29902]
- Add support for loading input configuration from external configuration files in standalone mode. You can load inputs from YAML configuration files under the folder `{path.config}/inputs.d`. {pull}30087[30087]
- Changed the default policy selection logic. When an agent is unmanaged and no policy id/name has been specified upon enroll, the agent will select a random unmanaged policy. {issue}29774[29774] {pull}30256[30256]
92 changes: 78 additions & 14 deletions x-pack/elastic-agent/pkg/agent/cmd/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@ import (
)

const (
requestRetrySleepEnv = "KIBANA_REQUEST_RETRY_SLEEP"
maxRequestRetriesEnv = "KIBANA_REQUEST_RETRY_COUNT"
defaultRequestRetrySleep = "1s" // sleep 1 sec between retries for HTTP requests
defaultMaxRequestRetries = "30" // maximum number of retries for HTTP requests
defaultStateDirectory = "/usr/share/elastic-agent/state" // directory that will hold the state data
requestRetrySleepEnv = "KIBANA_REQUEST_RETRY_SLEEP"
maxRequestRetriesEnv = "KIBANA_REQUEST_RETRY_COUNT"
defaultRequestRetrySleep = "1s" // sleep 1 sec between retries for HTTP requests
defaultMaxRequestRetries = "30" // maximum number of retries for HTTP requests
defaultStateDirectory = "/usr/share/elastic-agent/state" // directory that will hold the state data
defaultFleetPackagePolicyName = "fleet-server-policy"
lykkin marked this conversation as resolved.
Show resolved Hide resolved
)

var (
Expand Down Expand Up @@ -498,7 +499,44 @@ func kibanaFetchPolicy(cfg setupConfig, client *kibana.Client, streams *cli.IOSt
if err != nil {
return nil, err
}
return findPolicy(cfg, policies.Items)
packagePolicies, err := kibanaFetchPackagePolicies(cfg, client, streams)
lykkin marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}
return findPolicy(cfg, policies.Items, packagePolicies)
lykkin marked this conversation as resolved.
Show resolved Hide resolved
}

func kibanaFetchPackagePolicies(cfg setupConfig, client *kibana.Client, streams *cli.IOStreams) (*packagePolicyResponse, error) {
var packagePolicies kibanaPackagePolicies
err := performGET(cfg, client, "/api/fleet/package_policies", &packagePolicies, streams.Err, "Kibana fetch package policies")
lykkin marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}
return separatePackagePolicies(&packagePolicies), nil
}

func separatePackagePolicies(packagePolicies *kibanaPackagePolicies) *packagePolicyResponse {
result := packagePolicyResponse{
Fleet: make(map[string]struct{}),
NonFleet: make(map[string]struct{}),
}
for _, packagePolicy := range packagePolicies.Items {
policyID := packagePolicy.PolicyID
if packagePolicy.Package.Name == "fleet_server" {
lykkin marked this conversation as resolved.
Show resolved Hide resolved
// if we have previously marked a policy as unmanaged, clear that marking
if _, ok := result.NonFleet[policyID]; ok {
delete(result.NonFleet, policyID)
}

result.Fleet[policyID] = struct{}{}
} else {
// only mark new policies as unmanaged
if _, ok := result.Fleet[policyID]; !ok {
result.NonFleet[policyID] = struct{}{}
}
}
}
lykkin marked this conversation as resolved.
Show resolved Hide resolved
return &result
}

func kibanaFetchToken(cfg setupConfig, client *kibana.Client, policy *kibanaPolicy, streams *cli.IOStreams, tokenName string) (string, error) {
Expand Down Expand Up @@ -541,12 +579,13 @@ func kibanaClient(cfg kibanaConfig, headers map[string]string) (*kibana.Client,
}, 0, "Elastic-Agent")
}

func findPolicy(cfg setupConfig, policies []kibanaPolicy) (*kibanaPolicy, error) {
func findPolicy(cfg setupConfig, policies []kibanaPolicy, packagePolicies *packagePolicyResponse) (*kibanaPolicy, error) {
policyID := ""
policyName := cfg.Fleet.TokenPolicyName
if cfg.FleetServer.Enable {
policyID = cfg.FleetServer.PolicyID
}
var fallbackPolicy *kibanaPolicy
for _, policy := range policies {
if policyID != "" {
if policyID == policy.ID {
Expand All @@ -557,15 +596,23 @@ func findPolicy(cfg setupConfig, policies []kibanaPolicy) (*kibanaPolicy, error)
return &policy, nil
}
} else if cfg.FleetServer.Enable {
if policy.IsDefaultFleetServer {
if _, ok := packagePolicies.Fleet[policy.ID]; ok && fallbackPolicy == nil {
fallbackPolicy = &kibanaPolicy{}
*fallbackPolicy = policy
}
if policy.ID == defaultFleetPackagePolicyName {
return &policy, nil
}
} else {
if policy.IsDefault {
if _, ok := packagePolicies.NonFleet[policy.ID]; ok {
return &policy, nil
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the added logging and making it explicit this will helps us.

}

if fallbackPolicy != nil {
return fallbackPolicy, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@blakerouse I need to relearn the quirks of the enrollment process, but should we just error out?

return nil, fmt.Errorf(`unable to find policy named "%s"`, policyName)
}

Expand Down Expand Up @@ -898,12 +945,29 @@ func copyFile(destPath string, srcPath string, mode os.FileMode) error {
return err
}

type kibanaPackage struct {
Name string `json:"name"`
}

type packagePolicyResponse struct {
Fleet map[string]struct{}
NonFleet map[string]struct{}
}

type kibanaPackagePolicy struct {
PolicyID string `json:"policy_id"`
Package kibanaPackage `json:"package"`
}

type kibanaPackagePolicies struct {
Items []kibanaPackagePolicy `json:"items"`
}

type kibanaPolicy struct {
ID string `json:"id"`
Name string `json:"name"`
Status string `json:"status"`
IsDefault bool `json:"is_default"`
IsDefaultFleetServer bool `json:"is_default_fleet_server"`
ID string `json:"id"`
Name string `json:"name"`
Status string `json:"status"`
PackagePolicies []string `json:"package_policies"`
}

type kibanaPolicies struct {
Expand Down
Loading