@@ -43,7 +43,11 @@ import (
4343 "github.com/elastic/go-elasticsearch/v7"
4444)
4545
46- const startContainersTimeout = 5 * time .Minute
46+ const (
47+ startContainersTimeout = 5 * time .Minute
48+
49+ defaultFleetServerPort = "8220"
50+ )
4751
4852// StartStackContainers starts Docker containers for Elasticsearch and Kibana.
4953//
@@ -91,9 +95,7 @@ func NewUnstartedElasticsearchContainer() (*ElasticsearchContainer, error) {
9195 Image : container .Image ,
9296 AutoRemove : true ,
9397 }
94- waitFor := wait .ForHTTP ("/" )
95- waitFor .Port = "9200/tcp"
96- req .WaitingFor = waitFor
98+ req .WaitingFor = wait .ForHTTP ("/" ).WithPort ("9200/tcp" )
9799
98100 for port := range containerDetails .Config .ExposedPorts {
99101 req .ExposedPorts = append (req .ExposedPorts , string (port ))
@@ -252,30 +254,30 @@ func NewUnstartedElasticAgentContainer() (*ElasticAgentContainer, error) {
252254 }
253255 defer docker .Close ()
254256
255- kibanaContainer , err := stackContainerInfo (context .Background (), docker , "kibana " )
257+ esContainer , err := stackContainerInfo (context .Background (), docker , "elasticsearch " )
256258 if err != nil {
257259 return nil , err
258260 }
259- kibanaContainerDetails , err := docker .ContainerInspect (context .Background (), kibanaContainer .ID )
261+ esContainerDetails , err := docker .ContainerInspect (context .Background (), esContainer .ID )
260262 if err != nil {
261263 return nil , err
262264 }
263265
264- var kibanaIPAddress string
266+ var esIPAddress string
265267 var networks []string
266- for network , settings := range kibanaContainerDetails .NetworkSettings .Networks {
268+ for network , settings := range esContainerDetails .NetworkSettings .Networks {
267269 networks = append (networks , network )
268- if kibanaIPAddress == "" && settings .IPAddress != "" {
269- kibanaIPAddress = settings .IPAddress
270+ if esIPAddress == "" && settings .IPAddress != "" {
271+ esIPAddress = settings .IPAddress
270272 }
271273 }
272- kibanaURL := & url.URL {
274+ esURL := & url.URL {
273275 Scheme : "http" ,
274- Host : net .JoinHostPort (kibanaIPAddress , apmservertest .KibanaPort ()),
276+ Host : net .JoinHostPort (esIPAddress , apmservertest .ElasticsearchPort ()),
275277 }
276278
277- // Use the same stack version as used for Kibana .
278- agentImageVersion := kibanaContainer .Image [strings .LastIndex (kibanaContainer .Image , ":" )+ 1 :]
279+ // Use the same stack version as used for Elasticsearch .
280+ agentImageVersion := esContainer .Image [strings .LastIndex (esContainer .Image , ":" )+ 1 :]
279281 agentImage := "docker.elastic.co/beats/elastic-agent:" + agentImageVersion
280282 if err := pullDockerImage (context .Background (), docker , agentImage ); err != nil {
281283 return nil , err
@@ -293,11 +295,6 @@ func NewUnstartedElasticAgentContainer() (*ElasticAgentContainer, error) {
293295 AutoRemove : true ,
294296 Networks : networks ,
295297 Env : map [string ]string {
296- "KIBANA_HOST" : kibanaURL .String (),
297-
298- // TODO(axw) remove once https://github.com/elastic/elastic-agent-client/issues/20 is fixed
299- "GODEBUG" : "x509ignoreCN=0" ,
300-
301298 // NOTE(axw) because we bind-mount the apm-server artifacts in, they end up owned by the
302299 // current user rather than root. Disable Beats's strict permission checks to avoid resulting
303300 // complaints, as they're irrelevant to these system tests.
@@ -307,15 +304,17 @@ func NewUnstartedElasticAgentContainer() (*ElasticAgentContainer, error) {
307304 return & ElasticAgentContainer {
308305 request : req ,
309306 installDir : agentInstallDir ,
307+ elasticsearchURL : esURL .String (),
310308 StackVersion : agentImageVersion ,
311309 BindMountInstall : make (map [string ]string ),
312310 }, nil
313311}
314312
315313// ElasticAgentContainer represents an ephemeral Elastic Agent container.
316314type ElasticAgentContainer struct {
317- container testcontainers.Container
318- request testcontainers.ContainerRequest
315+ container testcontainers.Container
316+ request testcontainers.ContainerRequest
317+ elasticsearchURL string // used by Fleet Server only
319318
320319 // installDir holds the location of the "install" directory inside
321320 // the Elastic Agent container.
@@ -325,6 +324,10 @@ type ElasticAgentContainer struct {
325324 // can be bind-mounted.
326325 installDir string
327326
327+ // FleetServer controls whether this Elastic Agent bootstraps
328+ // Fleet Server.
329+ FleetServer bool
330+
328331 // StackVersion holds the stack version of the container image,
329332 // e.g. 8.0.0-SNAPSHOT.
330333 StackVersion string
@@ -335,6 +338,12 @@ type ElasticAgentContainer struct {
335338 // WaitingFor holds an optional wait strategy.
336339 WaitingFor wait.Strategy
337340
341+ // FleetServerURL holds the Fleet Server URL to enroll into.
342+ //
343+ // This will be populated by Start if FleetServer is true, using
344+ // one of the container's network aliases.
345+ FleetServerURL string
346+
338347 // Addrs holds the "host:port" address for each exposed port.
339348 // This will be populated by Start.
340349 Addrs []string
@@ -361,14 +370,27 @@ func (c *ElasticAgentContainer) Start() error {
361370 defer cancel ()
362371
363372 // Update request from user-definable fields.
364- if c .FleetEnrollmentToken != "" {
373+ if c .FleetServer {
374+ c .request .Env ["FLEET_SERVER_ENABLE" ] = "1"
375+ c .request .Env ["FLEET_SERVER_HOST" ] = "0.0.0.0"
376+ c .request .Env ["FLEET_SERVER_PORT" ] = defaultFleetServerPort
377+ c .request .Env ["FLEET_SERVER_INSECURE_HTTP" ] = "1" // expose Fleet Server over HTTP
378+ c .request .Env ["FLEET_SERVER_ELASTICSEARCH_HOST" ] = c .elasticsearchURL
379+ c .request .Env ["FLEET_SERVER_ELASTICSEARCH_USERNAME" ] = adminElasticsearchUser
380+ c .request .Env ["FLEET_SERVER_ELASTICSEARCH_PASSWORD" ] = adminElasticsearchPass
381+
382+ c .request .WaitingFor = wait .ForHTTP ("/api/status" ).WithPort (defaultFleetServerPort + "/tcp" )
383+ c .request .ExposedPorts = []string {defaultFleetServerPort }
384+ } else if c .FleetEnrollmentToken != "" {
365385 c .request .Env ["FLEET_ENROLL" ] = "1"
366386 c .request .Env ["FLEET_ENROLLMENT_TOKEN" ] = c .FleetEnrollmentToken
367387 c .request .Env ["FLEET_INSECURE" ] = "1"
368- c .request .Env ["FLEET_URL" ] = "http://kibana:5601"
388+ c .request .Env ["FLEET_URL" ] = c .FleetServerURL
389+ }
390+ c .request .ExposedPorts = append (c .request .ExposedPorts , c .ExposedPorts ... )
391+ if c .WaitingFor != nil {
392+ c .request .WaitingFor = c .WaitingFor
369393 }
370- c .request .ExposedPorts = c .ExposedPorts
371- c .request .WaitingFor = c .WaitingFor
372394 c .request .BindMounts = map [string ]string {}
373395 for source , target := range c .BindMountInstall {
374396 c .request .BindMounts [source ] = path .Join (c .installDir , target )
@@ -390,15 +412,33 @@ func (c *ElasticAgentContainer) Start() error {
390412 return err
391413 }
392414 if len (ports ) > 0 {
393- ip , err := container .Host (ctx )
415+ hostIP , err := container .Host (ctx )
394416 if err != nil {
395417 return err
396418 }
397419 for _ , portbindings := range ports {
398420 for _ , pb := range portbindings {
399- c .Addrs = append (c .Addrs , net .JoinHostPort (ip , pb .HostPort ))
421+ c .Addrs = append (c .Addrs , net .JoinHostPort (hostIP , pb .HostPort ))
422+ }
423+ }
424+ }
425+ if c .FleetServer {
426+ networkAliases , err := container .NetworkAliases (ctx )
427+ if err != nil {
428+ return err
429+ }
430+ var networkAlias string
431+ for _ , networkAliases := range networkAliases {
432+ if len (networkAliases ) > 0 {
433+ networkAlias = networkAliases [0 ]
434+ break
400435 }
401436 }
437+ if networkAlias == "" {
438+ return errors .New ("no network alias found" )
439+ }
440+ fleetServerURL := & url.URL {Scheme : "http" , Host : net .JoinHostPort (networkAlias , defaultFleetServerPort )}
441+ c .FleetServerURL = fleetServerURL .String ()
402442 }
403443
404444 c .container = container
0 commit comments