From ff5908a376f193e28211a84cb9579b9ee944d2ff Mon Sep 17 00:00:00 2001 From: Marc Lopez Rubio Date: Thu, 30 Dec 2021 10:38:07 +0800 Subject: [PATCH 1/2] compose: Use service tokens for `fleet-server` This patch updates the current `fleet-server` container to use a custom entrypoint which creates a service token and uses it. This is necessary since support to authenticate against Elasticsearch using username / password authentication has been removed from `8.0` onwards. Additionally, the docker-compose file has been updated to wait for the `fleet-server` container to be healthy before exiting. Signed-off-by: Marc Lopez Rubio --- docker-compose.yml | 5 +++-- testing/docker/fleet-server/docker-entrypoint.sh | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100755 testing/docker/fleet-server/docker-entrypoint.sh diff --git a/docker-compose.yml b/docker-compose.yml index 11f35e716d3..69d03b8bba6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,6 +7,7 @@ services: depends_on: elasticsearch: { condition: service_healthy } kibana: { condition: service_healthy } + fleet-server: { condition: service_healthy } elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:8.1.0-dbc834fd-SNAPSHOT @@ -63,6 +64,7 @@ services: fleet-server: image: docker.elastic.co/beats/elastic-agent:8.1.0-dbc834fd-SNAPSHOT + entrypoint: /entrypoint.sh ports: - 8220:8220 healthcheck: @@ -72,8 +74,6 @@ services: environment: FLEET_SERVER_ENABLE: "1" FLEET_SERVER_ELASTICSEARCH_HOST: http://elasticsearch:9200 - FLEET_SERVER_ELASTICSEARCH_USERNAME: "${ES_SUPERUSER_USER:-admin}" - FLEET_SERVER_ELASTICSEARCH_PASSWORD: "${ES_SUPERUSER_PASS:-changeme}" FLEET_SERVER_CERT: /etc/pki/tls/certs/fleet-server.pem FLEET_SERVER_CERT_KEY: /etc/pki/tls/private/fleet-server-key.pem FLEET_URL: https://fleet-server:8220 @@ -85,6 +85,7 @@ services: elasticsearch: { condition: service_healthy } kibana: { condition: service_healthy } volumes: + - "./testing/docker/fleet-server/docker-entrypoint.sh:/entrypoint.sh" - "./testing/docker/fleet-server/certificate.pem:/etc/pki/tls/certs/fleet-server.pem" - "./testing/docker/fleet-server/key.pem:/etc/pki/tls/private/fleet-server-key.pem" diff --git a/testing/docker/fleet-server/docker-entrypoint.sh b/testing/docker/fleet-server/docker-entrypoint.sh new file mode 100755 index 00000000000..8c08ac010d9 --- /dev/null +++ b/testing/docker/fleet-server/docker-entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +SERVICE_TOKEN_FILE=service_token + +if [[ ! -f ${SERVICE_TOKEN_FILE} ]]; then + jsonBody="$(curl -u${KIBANA_USERNAME}:${KIBANA_PASSWORD} -fsSL -XPOST \ + "${FLEET_SERVER_ELASTICSEARCH_HOST}/_security/service/elastic/fleet-server/credential/token/compose")" + # use grep and sed to get the service token value as we may not have jq or a similar tool on the instance + token=$(echo ${jsonBody} | grep -Eo '"value"[^}]*' | grep -Eo ':.*' | sed -r "s/://" | sed -r 's/"//g') + + echo ${token} > ${SERVICE_TOKEN_FILE} +fi + +export FLEET_SERVER_SERVICE_TOKEN=$(cat ${SERVICE_TOKEN_FILE}) + +/usr/bin/tini -s -- /usr/local/bin/docker-entrypoint From f65b78cc8d32cb9f42d0387f79c9abf0e726d262 Mon Sep 17 00:00:00 2001 From: Marc Lopez Rubio Date: Tue, 4 Jan 2022 10:07:18 +0800 Subject: [PATCH 2/2] Simplify ElasticAgentContainer constructor Signed-off-by: Marc Lopez Rubio --- systemtest/containers.go | 47 ++++++++++++++++++------------------- systemtest/sampling_test.go | 17 +++++++++++++- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/systemtest/containers.go b/systemtest/containers.go index f927e9b9b07..d5884b1cc70 100644 --- a/systemtest/containers.go +++ b/systemtest/containers.go @@ -31,7 +31,6 @@ import ( "net/url" "os" "os/exec" - "path/filepath" "runtime" "strings" "sync" @@ -314,26 +313,10 @@ func NewUnstartedElasticAgentContainer() (*ElasticAgentContainer, error) { return nil, err } - var fleetServerIPAddress string var networks []string - for network, settings := range fleetServerContainerDetails.NetworkSettings.Networks { + for network := range fleetServerContainerDetails.NetworkSettings.Networks { networks = append(networks, network) - if fleetServerIPAddress == "" && settings.IPAddress != "" { - fleetServerIPAddress = settings.IPAddress - } - } - fleetServerURL := &url.URL{ - Scheme: "https", - Host: net.JoinHostPort(fleetServerIPAddress, fleetServerPort), - } - containerCACertPath := "/etc/pki/tls/certs/fleet-ca.pem" - - _, filename, _, ok := runtime.Caller(0) - if !ok { - panic("could not locate systemtest directory") } - systemtestDir := filepath.Dir(filename) - hostCACertPath := filepath.Join(systemtestDir, "../testing/docker/fleet-server/ca.pem") // Use the same stack version as used for fleet-server. agentImageVersion := fleetServerContainer.Image[strings.LastIndex(fleetServerContainer.Image, ":")+1:] @@ -354,15 +337,31 @@ func NewUnstartedElasticAgentContainer() (*ElasticAgentContainer, error) { return nil, err } + // Reuse the ENV defined in the docker-compose container. + env := make(map[string]string) + for _, envVar := range fleetServerContainerDetails.Config.Env { + idx := strings.IndexRune(envVar, '=') + // Do not install the fleet-server integration or initialize the Kibana + // fleet. + dontSkip := !strings.HasPrefix(envVar, "KIBANA_FLEET_SETUP") && + !strings.HasPrefix(envVar, "FLEET_SERVER_ENABLE") + if idx > 0 && dontSkip { + env[envVar[:idx]] = envVar[idx+1:] + } + } + + // Reuse the bindmounts defined in the docker-compose container. + bindmounts := make(map[string]string) + for _, mount := range fleetServerContainerDetails.Mounts { + bindmounts[mount.Source] = mount.Destination + } + req := testcontainers.ContainerRequest{ Image: agentImage, - AutoRemove: true, Networks: networks, - BindMounts: map[string]string{hostCACertPath: containerCACertPath}, - Env: map[string]string{ - "FLEET_URL": fleetServerURL.String(), - "FLEET_CA": containerCACertPath, - }, + BindMounts: bindmounts, + Env: env, + AutoRemove: true, SkipReaper: true, // we use our own reaping logic } return &ElasticAgentContainer{ diff --git a/systemtest/sampling_test.go b/systemtest/sampling_test.go index 73b2df95df4..989c349649c 100644 --- a/systemtest/sampling_test.go +++ b/systemtest/sampling_test.go @@ -19,7 +19,9 @@ package systemtest_test import ( "context" + "encoding/json" "errors" + "os" "strings" "testing" "time" @@ -120,6 +122,19 @@ func TestTailSampling(t *testing.T) { tracer1.Flush(nil) tracer2.Flush(nil) + defer func() { + if t.Failed() { + t.Logf("Tracer 1 stats: %+v", tracer1.Stats()) + t.Logf("Tracer 2 stats: %+v", tracer2.Stats()) + + enc := json.NewEncoder(os.Stdout) + stats1 := apmIntegration1.getBeatsMonitoringStats(t, nil) + enc.Encode(stats1.Metrics["apm-server"].(map[string]interface{})["sampling"]) + stats2 := apmIntegration2.getBeatsMonitoringStats(t, nil) + enc.Encode(stats2.Metrics["apm-server"].(map[string]interface{})["sampling"]) + } + }() + // Flush the data stream while the test is running, as we have no // control over the settings for the sampled traces index template. refreshPeriodically(t, 250*time.Millisecond, "traces-apm.sampled-*") @@ -133,7 +148,7 @@ func TestTailSampling(t *testing.T) { }).WithSize(total).Do(context.Background(), &result, estest.WithCondition(result.Hits.MinHitsCondition(expected)), ) - require.NoError(t, err) + require.NoError(t, err, "did not find transaction type: %s", transactionType) assert.Equal(t, expected, len(result.Hits.Hits), transactionType) }