diff --git a/NOTICE.txt b/NOTICE.txt index 956efd00a7d..bac289d7bd0 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -1166,11 +1166,11 @@ SOFTWARE -------------------------------------------------------------------------------- Dependency : github.com/elastic/elastic-agent-libs -Version: v0.7.3 +Version: v0.7.4 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.7.3/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.7.4/LICENSE: Apache License Version 2.0, January 2004 diff --git a/changelog/fragments/1704397113-Add-mTLS-flags-to-install-enroll.yaml b/changelog/fragments/1704397113-Add-mTLS-flags-to-install-enroll.yaml new file mode 100644 index 00000000000..bf182210db3 --- /dev/null +++ b/changelog/fragments/1704397113-Add-mTLS-flags-to-install-enroll.yaml @@ -0,0 +1,38 @@ +# Kind can be one of: +# - breaking-change: a change to previously-documented behavior +# - deprecation: functionality that is being removed in a later release +# - bug-fix: fixes a problem in a previous version +# - enhancement: extends functionality but does not break or fix existing behavior +# - feature: new functionality +# - known-issue: problems that we are aware of in a given version +# - security: impacts on the security of a product or a user’s deployment. +# - upgrade: important information for someone upgrading from a prior version +# - other: does not fit into any of the other categories +kind: feature + +# Change summary; a 80ish characters long description of the change. +summary: Add mTLS flags to install/enroll + +# Long description; in case the summary is not enough to describe the change +# this field accommodate a description without length limits. +# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment. +description: | + Add mTLS flags to the install/enroll commands to allow fleet-server to + use client certs when connecting to Elasticsearch, and to allow + elastic-agent to use client certs when connecting to fleet-server. + Fleet-server will use the CAs passed in `--certificate-authorities` to + validate any client certs. Agent client certs do not influence auth in + fleet-server, an enrollment token, or API key is still required. + +# Affected component; a word indicating the component this changeset affects. +component: + +# PR URL; optional; the PR number that added the changeset. +# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added. +# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number. +# Please provide it if you are adding a fragment for a different PR. +#pr: https://github.com/owner/repo/1234 + +# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of). +# If not present is automatically filled by the tooling with the issue linked to the PR number. +#issue: https://github.com/owner/repo/1234 diff --git a/go.mod b/go.mod index 315ed0a956d..084ba2d5892 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/elastic/e2e-testing v1.1.0 github.com/elastic/elastic-agent-autodiscover v0.6.6 github.com/elastic/elastic-agent-client/v7 v7.8.0 - github.com/elastic/elastic-agent-libs v0.7.3 + github.com/elastic/elastic-agent-libs v0.7.4 github.com/elastic/elastic-agent-system-metrics v0.9.1 github.com/elastic/elastic-transport-go/v8 v8.3.0 github.com/elastic/go-elasticsearch/v8 v8.10.1 diff --git a/go.sum b/go.sum index 75b535dc25b..2e978d77a74 100644 --- a/go.sum +++ b/go.sum @@ -800,8 +800,8 @@ github.com/elastic/elastic-agent-autodiscover v0.6.6 h1:P1y0dDpbhJc7Uw/xe85irPEa github.com/elastic/elastic-agent-autodiscover v0.6.6/go.mod h1:chulyCAyZb/njMHgzkhC/yWnt8v/Y6eCRUhmFVnsA5o= github.com/elastic/elastic-agent-client/v7 v7.8.0 h1:GHFzDJIWpdgI0qDk5EcqbQJGvwTsl2E2vQK3/xe+MYQ= github.com/elastic/elastic-agent-client/v7 v7.8.0/go.mod h1:ihtjqJzYiIltlRhNruaSSc0ogxIhqPD5hOMKq16cI1s= -github.com/elastic/elastic-agent-libs v0.7.3 h1:tc6JDXYR+2XFMHJVv+7+M0OwAbZPxm3caLJEd943dlE= -github.com/elastic/elastic-agent-libs v0.7.3/go.mod h1:9hlSaDPm0XTrUWrZjwvckgov1pDHnsGyybzAjNe/1wA= +github.com/elastic/elastic-agent-libs v0.7.4 h1:/cmwOLwNAyJDNeR6sFIbHCDHDLPX2zAb/MAxQq7BRpo= +github.com/elastic/elastic-agent-libs v0.7.4/go.mod h1:pGMj5myawdqu+xE+WKvM5FQzKQ/MonikkWOzoFTJxaU= github.com/elastic/elastic-agent-system-metrics v0.9.1 h1:r0ofKHgPpl+W09ie7tzGcCDC0d4NZbQUv37rSgHf4FM= github.com/elastic/elastic-agent-system-metrics v0.9.1/go.mod h1:9C1UEfj0P687HAzZepHszN6zXA+2tN2Lx3Osvq1zby8= github.com/elastic/elastic-integration-corpus-generator-tool v0.5.0/go.mod h1:uf9N86y+UACGybdEhZLpwZ93XHWVhsYZAA4c2T2v6YM= diff --git a/internal/pkg/agent/cmd/enroll.go b/internal/pkg/agent/cmd/enroll.go index 95a13341a87..b6cd4071578 100644 --- a/internal/pkg/agent/cmd/enroll.go +++ b/internal/pkg/agent/cmd/enroll.go @@ -55,6 +55,8 @@ func addEnrollFlags(cmd *cobra.Command) { cmd.Flags().StringP("fleet-server-es-ca", "", "", "Path to certificate authority to use with communicate with elasticsearch") cmd.Flags().StringP("fleet-server-es-ca-trusted-fingerprint", "", "", "Elasticsearch certificate authority's SHA256 fingerprint") cmd.Flags().BoolP("fleet-server-es-insecure", "", false, "Disables validation of certificates") + cmd.Flags().StringP("fleet-server-es-cert", "", "", "Client certificate to use when connecting to Elasticsearch.") + cmd.Flags().StringP("fleet-server-es-cert-key", "", "", "Client private key to use when connecing to Elasticsearch.") cmd.Flags().StringP("fleet-server-service-token", "", "", "Service token to use for communication with elasticsearch") cmd.Flags().StringP("fleet-server-service-token-path", "", "", "Filepath for service token secret file to use for communication with elasticsearch") cmd.Flags().StringP("fleet-server-policy", "", "", "Start and run a Fleet Server on this specific policy") @@ -63,10 +65,13 @@ func addEnrollFlags(cmd *cobra.Command) { cmd.Flags().StringP("fleet-server-cert", "", "", "Certificate to use for exposed Fleet Server HTTPS endpoint") cmd.Flags().StringP("fleet-server-cert-key", "", "", "Private key to use for exposed Fleet Server HTTPS endpoint") cmd.Flags().StringP("fleet-server-cert-key-passphrase", "", "", "Path for private key passphrase file used to decrypt certificate key") + cmd.Flags().StringP("fleet-server-client-auth", "", "none", "Fleet-server mTLS client authentication for connecting elastic-agents. Must be one of [none, optional, required]") cmd.Flags().StringSliceP("header", "", []string{}, "Headers used in communication with elasticsearch") cmd.Flags().BoolP("fleet-server-insecure-http", "", false, "Expose Fleet Server over HTTP (not recommended; insecure)") cmd.Flags().StringP("certificate-authorities", "a", "", "Comma separated list of root certificate for server verifications") cmd.Flags().StringP("ca-sha256", "p", "", "Comma separated list of certificate authorities hash pins used for certificate verifications") + cmd.Flags().StringP("elastic-agent-cert", "", "", "Elastic-agent client certificate to use with fleet-server during authentication") + cmd.Flags().StringP("elastic-agent-cert-key", "", "", "Elastic-agent client certificate to use with fleet-server during authentication") cmd.Flags().BoolP("insecure", "i", false, "Allow insecure connection to fleet-server") cmd.Flags().StringP("staging", "", "", "Configures agent to download artifacts from a staging build") cmd.Flags().StringP("proxy-url", "", "", "Configures the proxy url") @@ -86,10 +91,26 @@ func validateEnrollFlags(cmd *cobra.Command) error { if ca != "" && !filepath.IsAbs(ca) { return errors.New("--certificate-authorities must be provided as an absolute path", errors.M("path", ca), errors.TypeConfig) } + cert, _ := cmd.Flags().GetString("elastic-agent-cert") + if cert != "" && !filepath.IsAbs(cert) { + return errors.New("--elastic-agent-cert must be provided as an absolute path", errors.M("path", cert), errors.TypeConfig) + } + key, _ := cmd.Flags().GetString("elastic-agent-cert-key") + if key != "" && !filepath.IsAbs(key) { + return errors.New("--elastic-agent-cert-key must be provided as an absolute path", errors.M("path", key), errors.TypeConfig) + } esCa, _ := cmd.Flags().GetString("fleet-server-es-ca") if esCa != "" && !filepath.IsAbs(esCa) { return errors.New("--fleet-server-es-ca must be provided as an absolute path", errors.M("path", esCa), errors.TypeConfig) } + esCert, _ := cmd.Flags().GetString("fleet-server-es-cert") + if esCert != "" && !filepath.IsAbs(esCert) { + return errors.New("--fleet-server-es-cert must be provided as an absolute path", errors.M("path", esCert), errors.TypeConfig) + } + esCertKey, _ := cmd.Flags().GetString("fleet-server-es-cert-key") + if esCertKey != "" && !filepath.IsAbs(esCertKey) { + return errors.New("--fleet-server-es-cert-key must be provided as an absolute path", errors.M("path", esCertKey), errors.TypeConfig) + } fCert, _ := cmd.Flags().GetString("fleet-server-cert") if fCert != "" && !filepath.IsAbs(fCert) { return errors.New("--fleet-server-cert must be provided as an absolute path", errors.M("path", fCert), errors.TypeConfig) @@ -110,6 +131,13 @@ func validateEnrollFlags(cmd *cobra.Command) error { if fPassphrase != "" && !filepath.IsAbs(fPassphrase) { return errors.New("--fleet-server-cert-key-passphrase must be provided as an absolute path", errors.M("path", fPassphrase), errors.TypeConfig) } + fClientAuth, _ := cmd.Flags().GetString("fleet-server-client-auth") + switch fClientAuth { + case "none", "optional", "required": + // NOTE we can split this case if we want to do additional checks when optional or required is passed. + default: + return errors.New("--fleet-server-client-auth must be one of [none, optional, required]") + } return nil } @@ -124,6 +152,8 @@ func buildEnrollmentFlags(cmd *cobra.Command, url string, token string) []string 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") fServiceToken, _ := cmd.Flags().GetString("fleet-server-service-token") fServiceTokenPath, _ := cmd.Flags().GetString("fleet-server-service-token-path") fPolicy, _ := cmd.Flags().GetString("fleet-server-policy") @@ -132,9 +162,12 @@ func buildEnrollmentFlags(cmd *cobra.Command, url string, token string) []string 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") fHeaders, _ := cmd.Flags().GetStringSlice("header") fInsecure, _ := cmd.Flags().GetBool("fleet-server-insecure-http") ca, _ := cmd.Flags().GetString("certificate-authorities") + cert, _ := cmd.Flags().GetString("elastic-agent-cert") + key, _ := cmd.Flags().GetString("elastic-agent-cert-key") sha256, _ := cmd.Flags().GetString("ca-sha256") insecure, _ := cmd.Flags().GetBool("insecure") staging, _ := cmd.Flags().GetString("staging") @@ -167,6 +200,14 @@ func buildEnrollmentFlags(cmd *cobra.Command, url string, token string) []string args = append(args, "--fleet-server-es-ca-trusted-fingerprint") args = append(args, fElasticSearchCASHA256) } + if fElasticSearchClientCert != "" { + args = append(args, "--fleet-server-es-cert") + args = append(args, fElasticSearchClientCert) + } + if fElasticSearchClientCertKey != "" { + args = append(args, "--fleet-server-es-cert-key") + args = append(args, fElasticSearchClientCertKey) + } if fServiceToken != "" { args = append(args, "--fleet-server-service-token") args = append(args, fServiceToken) @@ -199,6 +240,10 @@ func buildEnrollmentFlags(cmd *cobra.Command, url string, token string) []string args = append(args, "--fleet-server-cert-key-passphrase") args = append(args, fPassphrase) } + if fClientAuth != "" { + args = append(args, "--fleet-server-client-auth") + args = append(args, fClientAuth) + } if daemonTimeout != 0 { args = append(args, "--daemon-timeout") args = append(args, daemonTimeout.String()) @@ -220,6 +265,14 @@ func buildEnrollmentFlags(cmd *cobra.Command, url string, token string) []string args = append(args, "--certificate-authorities") args = append(args, ca) } + if cert != "" { + args = append(args, "--elastic-agent-cert") + args = append(args, cert) + } + if key != "" { + args = append(args, "--elastic-agent-cert-key") + args = append(args, key) + } if sha256 != "" { args = append(args, "--ca-sha256") args = append(args, sha256) @@ -328,6 +381,8 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command) error { 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") @@ -338,6 +393,7 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command) error { 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") @@ -352,6 +408,8 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command) error { 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") ctx := handleSignal(context.Background()) @@ -369,6 +427,8 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command) error { URL: url, CAs: CAs, CASha256: caSHA256, + Certificate: cert, + Key: key, Insecure: insecure, UserProvidedMetadata: make(map[string]interface{}), Staging: staging, @@ -385,6 +445,8 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command) error { ElasticsearchCA: fElasticSearchCA, ElasticsearchCASHA256: fElasticSearchCASHA256, ElasticsearchInsecure: fElasticSearchInsecure, + ElasticsearchCert: fElasticSearchClientCert, + ElasticsearchCertKey: fElasticSearchClientCertKey, ServiceToken: fServiceToken, ServiceTokenPath: fServiceTokenPath, PolicyID: fPolicy, @@ -393,6 +455,7 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command) error { Cert: fCert, CertKey: fCertKey, CertKeyPassphrasePath: fPassphrase, + ClientAuth: fClientAuth, Insecure: fInsecure, SpawnAgent: !fromInstall, Headers: mapFromEnvList(fHeaders), diff --git a/internal/pkg/agent/cmd/enroll_cmd.go b/internal/pkg/agent/cmd/enroll_cmd.go index 0d36e5cef36..dc9f4503dac 100644 --- a/internal/pkg/agent/cmd/enroll_cmd.go +++ b/internal/pkg/agent/cmd/enroll_cmd.go @@ -80,6 +80,8 @@ type enrollCmdFleetServerOption struct { ElasticsearchCA string ElasticsearchCASHA256 string ElasticsearchInsecure bool + ElasticsearchCert string + ElasticsearchCertKey string ServiceToken string ServiceTokenPath string PolicyID string @@ -89,6 +91,7 @@ type enrollCmdFleetServerOption struct { Cert string CertKey string CertKeyPassphrasePath string + ClientAuth string Insecure bool SpawnAgent bool Headers map[string]string @@ -101,6 +104,8 @@ type enrollCmdOption struct { InternalURL string `yaml:"-"` CAs []string `yaml:"ca,omitempty"` CASha256 []string `yaml:"ca_sha256,omitempty"` + Certificate string `yaml:"certificate,omitempty"` + Key string `yaml:"key,omitempty"` Insecure bool `yaml:"insecure,omitempty"` EnrollAPIKey string `yaml:"enrollment_key,omitempty"` Staging string `yaml:"staging,omitempty"` @@ -137,6 +142,12 @@ func (e *enrollCmdOption) remoteConfig() (remote.Config, error) { if e.Insecure { tlsCfg.VerificationMode = tlscommon.VerifyNone } + if e.Certificate != "" || e.Key != "" { + tlsCfg.Certificate = tlscommon.CertificateConfig{ + Certificate: e.Certificate, + Key: e.Key, + } + } cfg.Transport.TLS = &tlsCfg @@ -344,6 +355,8 @@ func (c *enrollCmd) fleetServerBootstrap(ctx context.Context, persistentConfig m c.options.FleetServer.PolicyID, c.options.FleetServer.Host, c.options.FleetServer.Port, c.options.FleetServer.InternalPort, c.options.FleetServer.Cert, c.options.FleetServer.CertKey, c.options.FleetServer.CertKeyPassphrasePath, c.options.FleetServer.ElasticsearchCA, c.options.FleetServer.ElasticsearchCASHA256, + c.options.CAs, c.options.FleetServer.ClientAuth, + c.options.FleetServer.ElasticsearchCert, c.options.FleetServer.ElasticsearchCertKey, c.options.FleetServer.Headers, c.options.ProxyURL, c.options.ProxyDisabled, @@ -570,6 +583,8 @@ func (c *enrollCmd) enroll(ctx context.Context, persistentConfig map[string]inte c.options.FleetServer.PolicyID, c.options.FleetServer.Host, c.options.FleetServer.Port, c.options.FleetServer.InternalPort, c.options.FleetServer.Cert, c.options.FleetServer.CertKey, c.options.FleetServer.CertKeyPassphrasePath, c.options.FleetServer.ElasticsearchCA, c.options.FleetServer.ElasticsearchCASHA256, + c.options.CAs, c.options.FleetServer.ClientAuth, + c.options.FleetServer.ElasticsearchCert, c.options.FleetServer.ElasticsearchCertKey, c.options.FleetServer.Headers, c.options.ProxyURL, c.options.ProxyDisabled, c.options.ProxyHeaders, c.options.FleetServer.ElasticsearchInsecure, @@ -921,6 +936,8 @@ func createFleetServerBootstrapConfig( connStr, serviceToken, serviceTokenPath, policyID, host string, port uint16, internalPort uint16, cert, key, passphrasePath, esCA, esCASHA256 string, + cas []string, clientAuth string, + esClientCert, esClientCertKey string, headers map[string]string, proxyURL string, proxyDisabled bool, @@ -951,6 +968,16 @@ func createFleetServerBootstrapConfig( es.TLS.CATrustedFingerprint = esCASHA256 } } + if esClientCert != "" || esClientCertKey != "" { + if es.TLS == nil { + es.TLS = &tlscommon.Config{} + } + + es.TLS.Certificate = tlscommon.CertificateConfig{ + Certificate: esClientCert, + Key: esClientCertKey, + } + } if host == "" { host = defaultFleetServerHost } @@ -988,7 +1015,7 @@ func createFleetServerBootstrapConfig( cfg.Server.Policy = &configuration.FleetServerPolicyConfig{ID: policyID} } if cert != "" || key != "" { - cfg.Server.TLS = &tlscommon.Config{ + cfg.Server.TLS = &tlscommon.ServerConfig{ Certificate: tlscommon.CertificateConfig{ Certificate: cert, Key: key, @@ -998,6 +1025,14 @@ func createFleetServerBootstrapConfig( if insecure { cfg.Server.TLS.VerificationMode = tlscommon.VerifyNone } + + cfg.Server.TLS.CAs = cas + + var cAuth tlscommon.TLSClientAuth + cfg.Server.TLS.ClientAuth = &cAuth + if err := cfg.Server.TLS.ClientAuth.Unpack(clientAuth); err != nil { + return nil, errors.New(err, "failed to unpack --fleet-server-client-auth", errors.TypeConfig) + } } if localFleetServer { diff --git a/internal/pkg/agent/cmd/enroll_cmd_test.go b/internal/pkg/agent/cmd/enroll_cmd_test.go index 2d28db5a4f8..d9c2f7207e4 100644 --- a/internal/pkg/agent/cmd/enroll_cmd_test.go +++ b/internal/pkg/agent/cmd/enroll_cmd_test.go @@ -9,7 +9,6 @@ import ( "context" "crypto/tls" "io" - "io/ioutil" "net" "net/http" "net/http/httptest" @@ -352,13 +351,15 @@ func TestValidateArgs(t *testing.T) { require.NoError(t, err) args := buildEnrollmentFlags(cmd, url, enrolmentToken) require.NotNil(t, args) - require.Equal(t, len(args), 9) + require.Equal(t, len(args), 11) require.Contains(t, args, "--tag") require.Contains(t, args, "windows") require.Contains(t, args, "production") require.Contains(t, args, "--insecure") require.Contains(t, args, enrolmentToken) require.Contains(t, args, url) + require.Contains(t, args, "--fleet-server-client-auth") + require.Contains(t, args, "none") cleanedTags := cleanTags(args) require.Contains(t, cleanedTags, "windows") require.Contains(t, cleanedTags, "production") @@ -372,12 +373,14 @@ func TestValidateArgs(t *testing.T) { require.Contains(t, args, "--tag") require.Contains(t, args, "windows") require.Contains(t, args, " production") + require.Contains(t, args, "--fleet-server-client-auth") + require.Contains(t, args, "none") cleanedTags := cleanTags(args) require.Contains(t, cleanedTags, "windows") require.Contains(t, cleanedTags, "production") // Validate that we remove the duplicates - require.Equal(t, len(args), 10) - require.Equal(t, len(cleanedTags), 7) + require.Equal(t, len(args), 12) + require.Equal(t, len(cleanedTags), 9) }) t.Run("valid tag and empty tag", func(t *testing.T) { @@ -388,6 +391,8 @@ func TestValidateArgs(t *testing.T) { require.Contains(t, args, "--tag") require.Contains(t, args, "windows") require.Contains(t, args, " ") + require.Contains(t, args, "--fleet-server-client-auth") + require.Contains(t, args, "none") cleanedTags := cleanTags(args) require.Contains(t, cleanedTags, "windows") require.NotContains(t, cleanedTags, " ") @@ -406,6 +411,32 @@ func TestValidateArgs(t *testing.T) { require.Contains(t, args, "--fleet-server-service-token-path") require.Contains(t, args, "/path/to/token") }) + + t.Run("fleet-es client certificates are passed", func(t *testing.T) { + cmd := newEnrollCommandWithArgs([]string{}, streams) + err := cmd.Flags().Set("fleet-server-es-cert", "/path/to/cert") + require.NoError(t, err) + err = cmd.Flags().Set("fleet-server-es-cert-key", "/path/to/key") + require.NoError(t, err) + args := buildEnrollmentFlags(cmd, url, enrolmentToken) + require.Contains(t, args, "--fleet-server-es-cert") + require.Contains(t, args, "/path/to/cert") + require.Contains(t, args, "--fleet-server-es-cert-key") + require.Contains(t, args, "/path/to/key") + }) + + t.Run("elastic-agent client certificates are passed", func(t *testing.T) { + cmd := newEnrollCommandWithArgs([]string{}, streams) + err := cmd.Flags().Set("elastic-agent-cert", "/path/to/cert") + require.NoError(t, err) + err = cmd.Flags().Set("elastic-agent-cert-key", "/path/to/key") + require.NoError(t, err) + args := buildEnrollmentFlags(cmd, url, enrolmentToken) + require.Contains(t, args, "--elastic-agent-cert") + require.Contains(t, args, "/path/to/cert") + require.Contains(t, args, "--elastic-agent-cert-key") + require.Contains(t, args, "/path/to/key") + }) } func TestValidateEnrollFlags(t *testing.T) { @@ -478,7 +509,7 @@ func withTLSServer( } func bytesToTMPFile(b []byte) (string, error) { - f, err := ioutil.TempFile("", "prefix") + f, err := os.CreateTemp("", "prefix") if err != nil { return "", err } diff --git a/internal/pkg/agent/cmd/install_test.go b/internal/pkg/agent/cmd/install_test.go index a94864568c8..221fda4648d 100644 --- a/internal/pkg/agent/cmd/install_test.go +++ b/internal/pkg/agent/cmd/install_test.go @@ -9,7 +9,6 @@ package cmd import ( "testing" - "github.com/spf13/cobra" "github.com/stretchr/testify/require" "github.com/elastic/elastic-agent/internal/pkg/agent/application/paths" @@ -52,10 +51,11 @@ func TestInvalidBasePath(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { streams := cli.NewIOStreams() - cmd := cobra.Command{} - cmd.Flags().String(flagInstallBasePath, test.basePath, "") + cmd := newInstallCommandWithArgs([]string{}, streams) + err := cmd.Flags().Set(flagInstallBasePath, test.basePath) + require.NoError(t, err) - err := installCmd(streams, &cmd) + err = installCmd(streams, cmd) if test.expectedError == "" { require.NoError(t, err) diff --git a/internal/pkg/agent/cmd/install_windows_test.go b/internal/pkg/agent/cmd/install_windows_test.go index 58afb650e8b..855f1107146 100644 --- a/internal/pkg/agent/cmd/install_windows_test.go +++ b/internal/pkg/agent/cmd/install_windows_test.go @@ -9,7 +9,6 @@ package cmd import ( "testing" - "github.com/spf13/cobra" "github.com/stretchr/testify/require" "github.com/elastic/elastic-agent/internal/pkg/agent/application/paths" @@ -52,10 +51,11 @@ func TestInvalidBasePath(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { streams := cli.NewIOStreams() - cmd := cobra.Command{} - cmd.Flags().String(flagInstallBasePath, test.basePath, "") + cmd := newInstallCommandWithArgs([]string{}, streams) + err := cmd.Flags().Set(flagInstallBasePath, test.basePath) + require.NoError(t, err) - err := installCmd(streams, &cmd) + err = installCmd(streams, cmd) if test.expectedError == "" { require.NoError(t, err) diff --git a/internal/pkg/agent/configuration/fleet_server.go b/internal/pkg/agent/configuration/fleet_server.go index 5d541ba3386..7e1290df758 100644 --- a/internal/pkg/agent/configuration/fleet_server.go +++ b/internal/pkg/agent/configuration/fleet_server.go @@ -19,7 +19,7 @@ type FleetServerConfig struct { Host string `config:"host" yaml:"host,omitempty"` Port uint16 `config:"port" yaml:"port,omitempty"` InternalPort uint16 `config:"internal_port" yaml:"internal_port,omitempty"` - TLS *tlscommon.Config `config:"ssl" yaml:"ssl,omitempty"` + TLS *tlscommon.ServerConfig `config:"ssl" yaml:"ssl,omitempty"` } // FleetServerPolicyConfig is the configuration for the policy Fleet Server should run on.