From c60da8f7c1134d7cf3ec13c01ceb5e64c0e5b174 Mon Sep 17 00:00:00 2001 From: Blake Rouse Date: Wed, 14 Apr 2021 15:16:25 -0400 Subject: [PATCH] Add --fleet-server-service-token. Rename --fleet-server to --fleet-server-es. (#25083) * Add --fleet-server-service-token. Rename --fleet-server to --fleet-server-es. * Add changelog. (cherry picked from commit f84ee649c525387ab7bf1c6d997d8e2fd3922c95) --- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 1 + .../elastic-agent/pkg/agent/cmd/container.go | 29 +++++++++----- x-pack/elastic-agent/pkg/agent/cmd/enroll.go | 24 +++++++---- .../elastic-agent/pkg/agent/cmd/enroll_cmd.go | 11 +++-- x-pack/elastic-agent/pkg/agent/cmd/install.go | 2 +- .../pkg/agent/configuration/fleet_server.go | 40 +++++++++++-------- 6 files changed, 67 insertions(+), 40 deletions(-) diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index f476f789c70..5e2aa2272ca 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -86,3 +86,4 @@ - Add STATE_PATH, CONFIG_PATH, LOGS_PATH to Elastic Agent docker image {pull}24817[24817] - Add status subcommand {pull}24856[24856] - Add leader_election provider for k8s {pull}24267[24267] +- Add --fleet-server-service-token and FLEET_SERVER_SERVICE_TOKEN options {pull}25083[25083] diff --git a/x-pack/elastic-agent/pkg/agent/cmd/container.go b/x-pack/elastic-agent/pkg/agent/cmd/container.go index 83ae0cf1039..f70484a027e 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/container.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/container.go @@ -80,6 +80,7 @@ The following actions are possible and grouped based on the actions. FLEET_SERVER_ELASTICSEARCH_USERNAME - elasticsearch username for Fleet Server [$ELASTICSEARCH_USERNAME] FLEET_SERVER_ELASTICSEARCH_PASSWORD - elasticsearch password for Fleet Server [$ELASTICSEARCH_PASSWORD] FLEET_SERVER_ELASTICSEARCH_CA - path to certificate authority to use with communicate with elasticsearch [$ELASTICSEARCH_CA] + FLEET_SERVER_SERVICE_TOKEN - service token to use for communication with elasticsearch FLEET_SERVER_POLICY_NAME - name of policy for the Fleet Server to use for itself [$FLEET_TOKEN_POLICY_NAME] FLEET_SERVER_POLICY_ID - policy ID for Fleet Server to use for itself ("Default Fleet Server policy" used when undefined) FLEET_SERVER_HOST - binding host for Fleet Server HTTP (overrides the policy) @@ -295,7 +296,10 @@ func buildEnrollArgs(cfg setupConfig, token string, policyID string) ([]string, if err != nil { return nil, err } - args = append(args, "--fleet-server", connStr) + args = append(args, "--fleet-server-es", connStr) + if cfg.FleetServer.Elasticsearch.ServiceToken != "" { + args = append(args, "--fleet-server-service-token", cfg.FleetServer.Elasticsearch.ServiceToken) + } if policyID == "" { policyID = cfg.FleetServer.PolicyID } @@ -303,7 +307,7 @@ func buildEnrollArgs(cfg setupConfig, token string, policyID string) ([]string, args = append(args, "--fleet-server-policy", policyID) } if cfg.FleetServer.Elasticsearch.CA != "" { - args = append(args, "--fleet-server-elasticsearch-ca", cfg.FleetServer.Elasticsearch.CA) + args = append(args, "--fleet-server-es-ca", cfg.FleetServer.Elasticsearch.CA) } if cfg.FleetServer.Host != "" { args = append(args, "--fleet-server-host", cfg.FleetServer.Host) @@ -351,6 +355,9 @@ func buildFleetServerConnStr(cfg fleetServerConfig) (string, error) { if u.Path != "" { path += "/" + strings.TrimLeft(u.Path, "/") } + if cfg.Elasticsearch.ServiceToken != "" { + return fmt.Sprintf("%s://%s%s", u.Scheme, u.Host, path), nil + } return fmt.Sprintf("%s://%s:%s@%s%s", u.Scheme, cfg.Elasticsearch.Username, cfg.Elasticsearch.Password, u.Host, path), nil } @@ -710,10 +717,11 @@ type setupConfig struct { } type elasticsearchConfig struct { - CA string `config:"ca"` - Host string `config:"host"` - Username string `config:"username"` - Password string `config:"password"` + CA string `config:"ca"` + Host string `config:"host"` + Username string `config:"username"` + Password string `config:"password"` + ServiceToken string `config:"service_token"` } type fleetConfig struct { @@ -767,10 +775,11 @@ func defaultAccessConfig() setupConfig { Cert: envWithDefault("", "FLEET_SERVER_CERT"), CertKey: envWithDefault("", "FLEET_SERVER_CERT_KEY"), Elasticsearch: elasticsearchConfig{ - Host: envWithDefault("http://elasticsearch:9200", "FLEET_SERVER_ELASTICSEARCH_HOST", "ELASTICSEARCH_HOST"), - Username: envWithDefault("elastic", "FLEET_SERVER_ELASTICSEARCH_USERNAME", "ELASTICSEARCH_USERNAME"), - Password: envWithDefault("changeme", "FLEET_SERVER_ELASTICSEARCH_PASSWORD", "ELASTICSEARCH_PASSWORD"), - CA: envWithDefault("", "FLEET_SERVER_ELASTICSEARCH_CA", "ELASTICSEARCH_CA"), + Host: envWithDefault("http://elasticsearch:9200", "FLEET_SERVER_ELASTICSEARCH_HOST", "ELASTICSEARCH_HOST"), + Username: envWithDefault("elastic", "FLEET_SERVER_ELASTICSEARCH_USERNAME", "ELASTICSEARCH_USERNAME"), + Password: envWithDefault("changeme", "FLEET_SERVER_ELASTICSEARCH_PASSWORD", "ELASTICSEARCH_PASSWORD"), + ServiceToken: envWithDefault("", "FLEET_SERVER_SERVICE_TOKEN"), + CA: envWithDefault("", "FLEET_SERVER_ELASTICSEARCH_CA", "ELASTICSEARCH_CA"), }, Enable: envBool("FLEET_SERVER_ENABLE"), Host: envWithDefault("", "FLEET_SERVER_HOST"), diff --git a/x-pack/elastic-agent/pkg/agent/cmd/enroll.go b/x-pack/elastic-agent/pkg/agent/cmd/enroll.go index ec7cec1211d..ebd06bfdd44 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/enroll.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/enroll.go @@ -52,8 +52,9 @@ func addEnrollFlags(cmd *cobra.Command) { cmd.Flags().StringP("url", "", "", "URL to enroll Agent into Fleet") cmd.Flags().StringP("kibana-url", "k", "", "URL of Kibana to enroll Agent into Fleet") cmd.Flags().StringP("enrollment-token", "t", "", "Enrollment token to use to enroll Agent into Fleet") - cmd.Flags().StringP("fleet-server", "", "", "Start and run a Fleet Server along side this Elastic Agent") - cmd.Flags().StringP("fleet-server-elasticsearch-ca", "", "", "Path to certificate authority to use with communicate with elasticsearch") + cmd.Flags().StringP("fleet-server-es", "", "", "Start and run a Fleet Server along side this Elastic Agent connecting to the provided elasticsearch") + cmd.Flags().StringP("fleet-server-es-ca", "", "", "Path to certificate authority to use with communicate with elasticsearch") + cmd.Flags().StringP("fleet-server-service-token", "", "", "Service token to use for communication with elasticsearch") cmd.Flags().StringP("fleet-server-policy", "", "", "Start and run a Fleet Server on this specific policy") cmd.Flags().StringP("fleet-server-host", "", "", "Fleet Server HTTP binding host (overrides the policy)") cmd.Flags().Uint16P("fleet-server-port", "", 0, "Fleet Server HTTP binding port (overrides the policy)") @@ -76,8 +77,9 @@ func buildEnrollmentFlags(cmd *cobra.Command, url string, token string) []string if token == "" { token, _ = cmd.Flags().GetString("enrollment-token") } - fServer, _ := cmd.Flags().GetString("fleet-server") - fElasticSearchCA, _ := cmd.Flags().GetString("fleet-server-elasticsearch-ca") + fServer, _ := cmd.Flags().GetString("fleet-server-es") + fElasticSearchCA, _ := cmd.Flags().GetString("fleet-server-es-ca") + fServiceToken, _ := cmd.Flags().GetString("fleet-server-service-token") fPolicy, _ := cmd.Flags().GetString("fleet-server-policy") fHost, _ := cmd.Flags().GetString("fleet-server-host") fPort, _ := cmd.Flags().GetUint16("fleet-server-port") @@ -99,13 +101,17 @@ func buildEnrollmentFlags(cmd *cobra.Command, url string, token string) []string args = append(args, token) } if fServer != "" { - args = append(args, "--fleet-server") + args = append(args, "--fleet-server-es") args = append(args, fServer) } if fElasticSearchCA != "" { - args = append(args, "--fleet-server-elasticsearch-ca") + args = append(args, "--fleet-server-es-ca") args = append(args, fElasticSearchCA) } + if fServiceToken != "" { + args = append(args, "--fleet-server-service-token") + args = append(args, fServiceToken) + } if fPolicy != "" { args = append(args, "--fleet-server-policy") args = append(args, fPolicy) @@ -210,8 +216,9 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command, args []string) error { url, _ = cmd.Flags().GetString("kibana-url") } enrollmentToken, _ := cmd.Flags().GetString("enrollment-token") - fServer, _ := cmd.Flags().GetString("fleet-server") - fElasticSearchCA, _ := cmd.Flags().GetString("fleet-server-elasticsearch-ca") + fServer, _ := cmd.Flags().GetString("fleet-server-es") + fElasticSearchCA, _ := cmd.Flags().GetString("fleet-server-es-ca") + fServiceToken, _ := cmd.Flags().GetString("fleet-server-service-token") fPolicy, _ := cmd.Flags().GetString("fleet-server-policy") fHost, _ := cmd.Flags().GetString("fleet-server-host") fPort, _ := cmd.Flags().GetUint16("fleet-server-port") @@ -238,6 +245,7 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command, args []string) error { FleetServer: enrollCmdFleetServerOption{ ConnStr: fServer, ElasticsearchCA: fElasticSearchCA, + ServiceToken: fServiceToken, PolicyID: fPolicy, Host: fHost, Port: fPort, diff --git a/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go b/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go index fade209dc51..a1e5beb9f59 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go @@ -67,6 +67,7 @@ type enrollCmd struct { type enrollCmdFleetServerOption struct { ConnStr string ElasticsearchCA string + ServiceToken string PolicyID string Host string Port uint16 @@ -218,7 +219,8 @@ func (c *enrollCmd) fleetServerBootstrap(ctx context.Context) (string, error) { } fleetConfig, err := createFleetServerBootstrapConfig( - c.options.FleetServer.ConnStr, c.options.FleetServer.PolicyID, + c.options.FleetServer.ConnStr, c.options.FleetServer.ServiceToken, + c.options.FleetServer.PolicyID, c.options.FleetServer.Host, c.options.FleetServer.Port, c.options.FleetServer.Cert, c.options.FleetServer.CertKey, c.options.FleetServer.ElasticsearchCA) if err != nil { @@ -388,7 +390,8 @@ func (c *enrollCmd) enroll(ctx context.Context) error { } if c.options.FleetServer.ConnStr != "" { serverConfig, err := createFleetServerBootstrapConfig( - c.options.FleetServer.ConnStr, c.options.FleetServer.PolicyID, + c.options.FleetServer.ConnStr, c.options.FleetServer.ServiceToken, + c.options.FleetServer.PolicyID, c.options.FleetServer.Host, c.options.FleetServer.Port, c.options.FleetServer.Cert, c.options.FleetServer.CertKey, c.options.FleetServer.ElasticsearchCA) if err != nil { @@ -692,8 +695,8 @@ func storeAgentInfo(s saver, reader io.Reader) error { return nil } -func createFleetServerBootstrapConfig(connStr string, policyID string, host string, port uint16, cert string, key string, esCA string) (*configuration.FleetAgentConfig, error) { - es, err := configuration.ElasticsearchFromConnStr(connStr) +func createFleetServerBootstrapConfig(connStr string, serviceToken string, policyID string, host string, port uint16, cert string, key string, esCA string) (*configuration.FleetAgentConfig, error) { + es, err := configuration.ElasticsearchFromConnStr(connStr, serviceToken) if err != nil { return nil, err } diff --git a/x-pack/elastic-agent/pkg/agent/cmd/install.go b/x-pack/elastic-agent/pkg/agent/cmd/install.go index 6df49f43ca6..3cffe1bb8df 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/install.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/install.go @@ -101,7 +101,7 @@ func installCmd(streams *cli.IOStreams, cmd *cobra.Command, args []string) error if url != "" && token != "" { askEnroll = false } - fleetServer, _ := cmd.Flags().GetString("fleet-server") + fleetServer, _ := cmd.Flags().GetString("fleet-server-es") if fleetServer != "" { askEnroll = false } diff --git a/x-pack/elastic-agent/pkg/agent/configuration/fleet_server.go b/x-pack/elastic-agent/pkg/agent/configuration/fleet_server.go index 939fb550482..e90f4bf3b1c 100644 --- a/x-pack/elastic-agent/pkg/agent/configuration/fleet_server.go +++ b/x-pack/elastic-agent/pkg/agent/configuration/fleet_server.go @@ -33,16 +33,17 @@ type FleetServerOutputConfig struct { // Elasticsearch is the configuration for elasticsearch. type Elasticsearch struct { - Protocol string `config:"protocol" yaml:"protocol"` - Hosts []string `config:"hosts" yaml:"hosts"` - Path string `config:"path" yaml:"path,omitempty"` - Username string `config:"username" yaml:"username"` - Password string `config:"password" yaml:"password"` - TLS *tlscommon.Config `config:"ssl" yaml:"ssl,omitempty"` + Protocol string `config:"protocol" yaml:"protocol"` + Hosts []string `config:"hosts" yaml:"hosts"` + Path string `config:"path" yaml:"path,omitempty"` + Username string `config:"username" yaml:"username,omitempty"` + Password string `config:"password" yaml:"password,omitempty"` + ServiceToken string `config:"service_token" yaml:"service_token,omitempty"` + TLS *tlscommon.Config `config:"ssl" yaml:"ssl,omitempty"` } // ElasticsearchFromConnStr returns an Elasticsearch configuration from the connection string. -func ElasticsearchFromConnStr(conn string) (Elasticsearch, error) { +func ElasticsearchFromConnStr(conn string, serviceToken string) (Elasticsearch, error) { u, err := url.Parse(conn) if err != nil { return Elasticsearch{}, err @@ -53,19 +54,24 @@ func ElasticsearchFromConnStr(conn string) (Elasticsearch, error) { if u.Host == "" { return Elasticsearch{}, errors.New("invalid connection string: must include a host") } + cfg := Elasticsearch{ + Protocol: u.Scheme, + Hosts: []string{u.Host}, + Path: u.Path, + TLS: nil, + } + if serviceToken != "" { + cfg.ServiceToken = serviceToken + return cfg, nil + } if u.User == nil || u.User.Username() == "" { - return Elasticsearch{}, errors.New("invalid connection string: must include a username") + return Elasticsearch{}, errors.New("invalid connection string: must include a username unless a service token is provided") } password, ok := u.User.Password() if !ok { - return Elasticsearch{}, errors.New("invalid connection string: must include a password") + return Elasticsearch{}, errors.New("invalid connection string: must include a password unless a service token is provided") } - return Elasticsearch{ - Protocol: u.Scheme, - Hosts: []string{u.Host}, - Path: u.Path, - Username: u.User.Username(), - Password: password, - TLS: nil, - }, nil + cfg.Username = u.User.Username() + cfg.Password = password + return cfg, nil }