in internal/pkg/agent/cmd/enroll_cmd.go [202:321]
func (c *enrollCmd) Execute(ctx context.Context, streams *cli.IOStreams) error {
var err error
defer c.stopAgent() // ensure its stopped no matter what
span, ctx := apm.StartSpan(ctx, "enroll", "app.internal")
defer func() {
apm.CaptureError(ctx, err).Send()
span.End()
}()
hasRoot, err := utils.HasRoot()
if err != nil {
return fmt.Errorf("checking if running with root/Administrator privileges: %w", err)
}
// Create encryption key from the agent before touching configuration
if !c.options.SkipCreateSecret {
opts := []vault.OptionFunc{vault.WithUnprivileged(!hasRoot)}
if c.options.FixPermissions != nil {
opts = append(opts, vault.WithVaultOwnership(*c.options.FixPermissions))
}
err = secret.CreateAgentSecret(ctx, opts...)
if err != nil {
return err
}
}
persistentConfig, err := getPersistentConfig(c.configPath)
if err != nil {
return err
}
// localFleetServer indicates that we start our internal fleet server. Agent
// will communicate to the internal fleet server on localhost only.
// Connection setup should disable proxies in that case.
localFleetServer := c.options.FleetServer.ConnStr != ""
if localFleetServer && !c.options.DelayEnroll {
token, err := c.fleetServerBootstrap(ctx, persistentConfig)
if err != nil {
return err
}
if c.options.EnrollAPIKey == "" && token != "" {
c.options.EnrollAPIKey = token
}
}
c.remoteConfig, err = c.options.remoteConfig()
if err != nil {
return errors.New(
err, "Error",
errors.TypeConfig,
errors.M(errors.MetaKeyURI, c.options.URL))
}
if localFleetServer {
// Ensure that the agent does not use a proxy configuration
// when connecting to the local fleet server.
// Note that when running fleet-server the enroll request will be sent to :8220,
// however when the agent is running afterward requests will be sent to :8221
c.remoteConfig.Transport.Proxy.Disable = true
}
c.client, err = fleetclient.NewWithConfig(c.log, c.remoteConfig)
if err != nil {
return errors.New(
err, "Error",
errors.TypeNetwork,
errors.M(errors.MetaKeyURI, c.options.URL))
}
if c.options.DelayEnroll {
if c.options.FleetServer.Host != "" {
return errors.New("--delay-enroll cannot be used with --fleet-server-es", errors.TypeConfig)
}
err = c.writeDelayEnroll(streams)
if err != nil {
// context for error already provided in writeDelayEnroll
return err
}
if c.options.FixPermissions != nil {
err = perms.FixPermissions(paths.Top(), perms.WithOwnership(*c.options.FixPermissions))
if err != nil {
return errors.New(err, "failed to fix permissions")
}
}
return nil
}
err = c.enrollWithBackoff(ctx, persistentConfig)
if err != nil {
return fmt.Errorf("fail to enroll: %w", err)
}
if c.options.FixPermissions != nil {
err = perms.FixPermissions(paths.Top(), perms.WithOwnership(*c.options.FixPermissions))
if err != nil {
return errors.New(err, "failed to fix permissions")
}
}
defer func() {
if err != nil {
fmt.Fprintf(streams.Err, "Something went wrong while enrolling the Elastic Agent: %v\n", err)
} else {
fmt.Fprintln(streams.Out, "Successfully enrolled the Elastic Agent.")
}
}()
if c.agentProc == nil && !c.options.SkipDaemonRestart {
if err = c.daemonReloadWithBackoff(ctx); err != nil {
c.log.Errorf("Elastic Agent might not be running; unable to trigger restart: %v", err)
return fmt.Errorf("could not reload agent daemon, unable to trigger restart: %w", err)
}
c.log.Info("Successfully triggered restart on running Elastic Agent.")
return nil
}
c.log.Info("Elastic Agent has been enrolled; start Elastic Agent")
return nil
}