in internal/pkg/agent/cmd/enroll.go [366:583]
func enroll(streams *cli.IOStreams, cmd *cobra.Command) error {
err := validateEnrollFlags(cmd)
if err != nil {
return err
}
fromInstall, _ := cmd.Flags().GetBool(fromInstallArg)
hasRoot, err := utils.HasRoot()
if err != nil {
return fmt.Errorf("checking if running with root/Administrator privileges: %w", err)
}
if hasRoot && !fromInstall {
binPath, err := os.Executable()
if err != nil {
return fmt.Errorf("error while getting executable path: %w", err)
}
isOwner, err := isOwnerExec(binPath)
if err != nil {
return fmt.Errorf("ran into an error while figuring out if user is allowed to execute the enroll command: %w", err)
}
if !isOwner {
return UserOwnerMismatchError
}
}
pathConfigFile := paths.ConfigFile()
rawConfig, err := config.LoadFile(pathConfigFile)
if err != nil {
return errors.New(err,
fmt.Sprintf("could not read configuration file %s", pathConfigFile),
errors.TypeFilesystem,
errors.M(errors.MetaKeyPath, pathConfigFile))
}
cfg, err := configuration.NewFromConfig(rawConfig)
if err != nil {
return errors.New(err,
fmt.Sprintf("could not parse configuration file %s", pathConfigFile),
errors.TypeFilesystem,
errors.M(errors.MetaKeyPath, pathConfigFile))
}
staging, _ := cmd.Flags().GetString("staging")
if staging != "" {
if len(staging) < 8 {
return errors.New(fmt.Errorf("invalid staging build hash; must be at least 8 characters"), "Error")
}
}
force, _ := cmd.Flags().GetBool("force")
if fromInstall {
force = true
}
// prompt only when it is not forced and is already enrolled
if !force && (cfg.Fleet != nil && cfg.Fleet.Enabled) {
confirm, err := cli.Confirm("This will replace your current settings. Do you want to continue?", true)
if err != nil {
return errors.New(err, "problem reading prompt response")
}
if !confirm {
fmt.Fprintln(streams.Out, "Enrollment was cancelled by the user")
return nil
}
}
// enroll is invoked either manually or from install with redirected IO
// no need to log to file
cfg.Settings.LoggingConfig.ToFiles = false
cfg.Settings.LoggingConfig.ToStderr = true
logger, err := logger.NewFromConfig("", cfg.Settings.LoggingConfig, cfg.Settings.EventLoggingConfig, false)
if err != nil {
return err
}
insecure, _ := cmd.Flags().GetBool("insecure")
url, _ := cmd.Flags().GetString("url")
enrollmentToken, _ := cmd.Flags().GetString("enrollment-token")
id, _ := cmd.Flags().GetString("id")
replaceToken, _ := cmd.Flags().GetString("replace-token")
fServer, _ := cmd.Flags().GetString("fleet-server-es")
fElasticSearchCA, _ := cmd.Flags().GetString("fleet-server-es-ca")
fElasticSearchCASHA256, _ := cmd.Flags().GetString("fleet-server-es-ca-trusted-fingerprint")
fElasticSearchInsecure, _ := cmd.Flags().GetBool("fleet-server-es-insecure")
fElasticSearchClientCert, _ := cmd.Flags().GetString("fleet-server-es-cert")
fElasticSearchClientCertKey, _ := cmd.Flags().GetString("fleet-server-es-cert-key")
fHeaders, _ := cmd.Flags().GetStringSlice("header")
fServiceToken, _ := cmd.Flags().GetString("fleet-server-service-token")
fServiceTokenPath, _ := cmd.Flags().GetString("fleet-server-service-token-path")
fPolicy, _ := cmd.Flags().GetString("fleet-server-policy")
fHost, _ := cmd.Flags().GetString("fleet-server-host")
fPort, _ := cmd.Flags().GetUint16("fleet-server-port")
fInternalPort, _ := cmd.Flags().GetUint16("fleet-server-internal-port")
fCert, _ := cmd.Flags().GetString("fleet-server-cert")
fCertKey, _ := cmd.Flags().GetString("fleet-server-cert-key")
fPassphrase, _ := cmd.Flags().GetString("fleet-server-cert-key-passphrase")
fClientAuth, _ := cmd.Flags().GetString("fleet-server-client-auth")
fInsecure, _ := cmd.Flags().GetBool("fleet-server-insecure-http")
proxyURL, _ := cmd.Flags().GetString("proxy-url")
proxyDisabled, _ := cmd.Flags().GetBool("proxy-disabled")
proxyHeaders, _ := cmd.Flags().GetStringSlice("proxy-header")
delayEnroll, _ := cmd.Flags().GetBool("delay-enroll")
daemonTimeout, _ := cmd.Flags().GetDuration("daemon-timeout")
enrollTimeout, _ := cmd.Flags().GetDuration("enroll-timeout")
fTimeout, _ := cmd.Flags().GetDuration("fleet-server-timeout")
skipDaemonReload, _ := cmd.Flags().GetBool("skip-daemon-reload")
tags, _ := cmd.Flags().GetStringSlice("tag")
caStr, _ := cmd.Flags().GetString("certificate-authorities")
CAs := cli.StringToSlice(caStr)
caSHA256str, _ := cmd.Flags().GetString("ca-sha256")
caSHA256 := cli.StringToSlice(caSHA256str)
cert, _ := cmd.Flags().GetString("elastic-agent-cert")
key, _ := cmd.Flags().GetString("elastic-agent-cert-key")
keyPassphrase, _ := cmd.Flags().GetString("elastic-agent-cert-key-passphrase")
ctx := handleSignal(context.Background())
if enrollTimeout > 0 {
eCtx, cancel := context.WithTimeout(ctx, enrollTimeout)
defer cancel()
ctx = eCtx
}
// On MacOS Ventura and above, fixing the permissions on enrollment during installation fails with the error:
// Error: failed to fix permissions: chown /Library/Elastic/Agent/data/elastic-agent-c13f91/elastic-agent.app: operation not permitted
// This is because we are fixing permissions twice, once during installation and again during the enrollment step.
// When we are enrolling as part of installation on MacOS, skip the second attempt to fix permissions.
var fixPermissions *utils.FileOwner
if fromInstall {
perms, err := getFileOwnerFromCmd(cmd)
if err != nil {
// no context is added because the error is clear and user facing
return err
}
fixPermissions = &perms
}
if runtime.GOOS == "darwin" {
fixPermissions = nil
}
options := enrollCmdOption{
EnrollAPIKey: enrollmentToken,
ID: id,
ReplaceToken: replaceToken,
URL: url,
CAs: CAs,
CASha256: caSHA256,
Certificate: cert,
Key: key,
KeyPassphrasePath: keyPassphrase,
Insecure: insecure,
UserProvidedMetadata: make(map[string]interface{}),
Staging: staging,
FixPermissions: fixPermissions,
ProxyURL: proxyURL,
ProxyDisabled: proxyDisabled,
ProxyHeaders: mapFromEnvList(proxyHeaders),
DelayEnroll: delayEnroll,
DaemonTimeout: daemonTimeout,
SkipDaemonRestart: skipDaemonReload,
Tags: tags,
FleetServer: enrollCmdFleetServerOption{
ConnStr: fServer,
ElasticsearchCA: fElasticSearchCA,
ElasticsearchCASHA256: fElasticSearchCASHA256,
ElasticsearchInsecure: fElasticSearchInsecure,
ElasticsearchCert: fElasticSearchClientCert,
ElasticsearchCertKey: fElasticSearchClientCertKey,
ServiceToken: fServiceToken,
ServiceTokenPath: fServiceTokenPath,
PolicyID: fPolicy,
Host: fHost,
Port: fPort,
Cert: fCert,
CertKey: fCertKey,
CertKeyPassphrasePath: fPassphrase,
ClientAuth: fClientAuth,
Insecure: fInsecure,
SpawnAgent: !fromInstall,
Headers: mapFromEnvList(fHeaders),
Timeout: fTimeout,
InternalPort: fInternalPort,
},
}
var storeOpts []storage.ReplaceOnSuccessStoreOptionFunc
var encryptOpts []storage.EncryptedOptionFunc
if fixPermissions != nil {
storeOpts = append(storeOpts, storage.ReplaceOnSuccessStoreWithOwnership(*fixPermissions))
encryptOpts = append(encryptOpts, storage.EncryptedStoreWithOwnership(*fixPermissions))
}
encStore, err := storage.NewEncryptedDiskStore(ctx, paths.AgentConfigFile(), encryptOpts...)
if err != nil {
return fmt.Errorf("failed to create encrypted disk store: %w", err)
}
store := storage.NewReplaceOnSuccessStore(
pathConfigFile,
application.DefaultAgentFleetConfig,
encStore,
storeOpts...,
)
c, err := newEnrollCmd(
logger,
&options,
pathConfigFile,
store,
nil,
)
if err != nil {
return err
}
return c.Execute(ctx, streams)
}