diff --git a/internal/pkg/agent/cmd/container.go b/internal/pkg/agent/cmd/container.go index 84db4685a5b..2b466db6aa1 100644 --- a/internal/pkg/agent/cmd/container.go +++ b/internal/pkg/agent/cmd/container.go @@ -503,6 +503,12 @@ func buildEnrollArgs(cfg setupConfig, token string, policyID string) ([]string, if token != "" { args = append(args, "--enrollment-token", token) } + if cfg.Fleet.ID != "" { + args = append(args, "--id", cfg.Fleet.ID) + } + if cfg.Fleet.ReplaceToken != "" { + args = append(args, "--replace-token", cfg.Fleet.ReplaceToken) + } if cfg.Fleet.DaemonTimeout != 0 { args = append(args, "--daemon-timeout") args = append(args, cfg.Fleet.DaemonTimeout.String()) diff --git a/internal/pkg/agent/cmd/enroll.go b/internal/pkg/agent/cmd/enroll.go index 534f89503f6..f7e7af52046 100644 --- a/internal/pkg/agent/cmd/enroll.go +++ b/internal/pkg/agent/cmd/enroll.go @@ -64,6 +64,8 @@ func newEnrollCommandWithArgs(_ []string, streams *cli.IOStreams) *cobra.Command func addEnrollFlags(cmd *cobra.Command) { cmd.Flags().StringP("url", "", "", "URL to enroll Agent into Fleet") cmd.Flags().StringP("enrollment-token", "t", "", "Enrollment token to use to enroll Agent into Fleet") + cmd.Flags().StringP("id", "", "", "Agent ID to use for enrollment into Fleet") + cmd.Flags().StringP("replace-token", "", "", "Replace token that that allows the Agent to be replace with the provided --id as long as this token matches") cmd.Flags().StringP("fleet-server-es", "", "", "Start and run a Fleet Server alongside this Elastic Agent connecting to the provided Elasticsearch") cmd.Flags().StringP("fleet-server-es-ca", "", "", "Path to certificate authority for Fleet Server to use to communicate with Elasticsearch") cmd.Flags().StringP("fleet-server-es-ca-trusted-fingerprint", "", "", "Elasticsearch certificate authority's SHA256 fingerprint for Fleet Server to use") @@ -172,6 +174,8 @@ func buildEnrollmentFlags(cmd *cobra.Command, url string, token string) []string if token == "" { token, _ = 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") @@ -213,6 +217,14 @@ func buildEnrollmentFlags(cmd *cobra.Command, url string, token string) []string args = append(args, "--enrollment-token") args = append(args, token) } + if id != "" { + args = append(args, "--id") + args = append(args, id) + } + if replaceToken != "" { + args = append(args, "--replace-token") + args = append(args, replaceToken) + } if fServer != "" { args = append(args, "--fleet-server-es") args = append(args, fServer) @@ -424,6 +436,8 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command) error { 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") @@ -480,6 +494,8 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command) error { options := enrollCmdOption{ EnrollAPIKey: enrollmentToken, + ID: id, + ReplaceToken: replaceToken, URL: url, CAs: CAs, CASha256: caSHA256, diff --git a/internal/pkg/agent/cmd/enroll_cmd.go b/internal/pkg/agent/cmd/enroll_cmd.go index 6c3df8e8998..ac36603bc5e 100644 --- a/internal/pkg/agent/cmd/enroll_cmd.go +++ b/internal/pkg/agent/cmd/enroll_cmd.go @@ -113,6 +113,8 @@ type enrollCmdOption struct { Key string `yaml:"key,omitempty"` KeyPassphrasePath string `yaml:"key_passphrase_path,omitempty"` Insecure bool `yaml:"insecure,omitempty"` + ID string `yaml:"id,omitempty"` + ReplaceToken string `yaml:"replace_token,omitempty"` EnrollAPIKey string `yaml:"enrollment_key,omitempty"` Staging string `yaml:"staging,omitempty"` ProxyURL string `yaml:"proxy_url,omitempty"` @@ -568,6 +570,8 @@ func (c *enrollCmd) enroll(ctx context.Context, persistentConfig map[string]inte r := &fleetapi.EnrollRequest{ EnrollAPIKey: c.options.EnrollAPIKey, Type: fleetapi.PermanentEnroll, + ID: c.options.ID, + ReplaceToken: c.options.ReplaceToken, Metadata: fleetapi.Metadata{ Local: metadata, UserProvided: c.options.UserProvidedMetadata, diff --git a/internal/pkg/agent/cmd/setup_config.go b/internal/pkg/agent/cmd/setup_config.go index 2fd3afad651..ae02ca9a6ca 100644 --- a/internal/pkg/agent/cmd/setup_config.go +++ b/internal/pkg/agent/cmd/setup_config.go @@ -18,6 +18,8 @@ type fleetConfig struct { CA string `config:"ca"` Enroll bool `config:"enroll"` EnrollmentToken string `config:"enrollment_token"` + ID string `config:"id"` + ReplaceToken string `config:"replace_token"` Force bool `config:"force"` Insecure bool `config:"insecure"` TokenName string `config:"token_name"` @@ -86,6 +88,8 @@ func defaultAccessConfig() (setupConfig, error) { CA: envWithDefault("", "FLEET_CA", "KIBANA_CA", "ELASTICSEARCH_CA"), Enroll: envBool("FLEET_ENROLL", "FLEET_SERVER_ENABLE"), EnrollmentToken: envWithDefault("", "FLEET_ENROLLMENT_TOKEN"), + ID: envWithDefault("", "ELASTIC_AGENT_ID"), + ReplaceToken: envWithDefault("", "FLEET_REPLACE_TOKEN"), Force: envBool("FLEET_FORCE"), Insecure: envBool("FLEET_INSECURE"), TokenName: envWithDefault("Default", "FLEET_TOKEN_NAME"), diff --git a/internal/pkg/fleetapi/enroll_cmd.go b/internal/pkg/fleetapi/enroll_cmd.go index 768b76cddfd..9bb0c947f07 100644 --- a/internal/pkg/fleetapi/enroll_cmd.go +++ b/internal/pkg/fleetapi/enroll_cmd.go @@ -88,16 +88,20 @@ func (p EnrollType) MarshalJSON() ([]byte, error) { // Example: // POST /api/fleet/agents/enroll // -// { -// "type": "PERMANENT", -// "metadata": { -// "local": { "os": "macos"}, -// "user_provided": { "region": "us-east"} -// } -// } +// { +// "type": "PERMANENT", +// "id": "custom-id", // optional +// "replace_token": "replacetokenvalue", // optional +// "metadata": { +// "local": { "os": "macos"}, +// "user_provided": { "region": "us-east"} +// } +// } type EnrollRequest struct { EnrollAPIKey string `json:"-"` Type EnrollType `json:"type"` + ID string `json:"id"` + ReplaceToken string `json:"replace_token"` Metadata Metadata `json:"metadata"` }