func()

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
}