Skip to content
This repository has been archived by the owner on Sep 17, 2024. It is now read-only.

Commit

Permalink
Merge pull request #181 from mdelapenya/remove-token
Browse files Browse the repository at this point in the history
fix: use the status of the agent by hostname
  • Loading branch information
mdelapenya authored Jul 20, 2020
2 parents 15d2db5 + 41cf3bf commit a457007
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 122 deletions.
147 changes: 80 additions & 67 deletions e2e/_suites/ingest-manager/fleet.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type FleetTestSuite struct {
ConfigID string // will be used to manage tokens
CurrentToken string // current enrollment token
CurrentTokenID string // current enrollment tokenID
Hostname string // the hostname of the container
}

func (fts *FleetTestSuite) contributeSteps(s *godog.Suite) {
Expand Down Expand Up @@ -64,8 +65,15 @@ func (fts *FleetTestSuite) anAgentIsDeployedToFleet() error {
}
fts.Cleanup = true

// get container hostname once
hostname, err := getContainerHostname(containerName)
if err != nil {
return err
}
fts.Hostname = hostname

// enroll the agent with a new token
tokenJSONObject, err := createFleetToken("name", fts.ConfigID)
tokenJSONObject, err := createFleetToken("Test token for "+hostname, fts.ConfigID)
if err != nil {
return err
}
Expand Down Expand Up @@ -132,23 +140,23 @@ func (fts *FleetTestSuite) setup() error {
func (fts *FleetTestSuite) theAgentIsListedInFleetAsOnline() error {
log.Debug("Checking agent is listed in Fleet as online")

agentsCount := 0.0
maxTimeout := 10 * time.Second
retryCount := 1

exp := e2e.GetExponentialBackOff(maxTimeout)

countAgentsFn := func() error {
count, err := countOnlineAgents()
if err != nil || count == 0 {
agentOnlineFn := func() error {
status, err := isAgentOnline(fts.Hostname)
if err != nil || !status {
if err == nil {
err = fmt.Errorf("The Agent is not online yet")
}

log.WithFields(log.Fields{
"retry": retryCount,
"onlineAgents": count,
"elapsedTime": exp.GetElapsedTime(),
"active": status,
"elapsedTime": exp.GetElapsedTime(),
"hostname": fts.Hostname,
"retry": retryCount,
}).Warn(err.Error())

retryCount++
Expand All @@ -157,25 +165,19 @@ func (fts *FleetTestSuite) theAgentIsListedInFleetAsOnline() error {
}

log.WithFields(log.Fields{
"elapsedTime": exp.GetElapsedTime(),
"onlineAgents": count,
"retries": retryCount,
"active": status,
"elapsedTime": exp.GetElapsedTime(),
"hostname": fts.Hostname,
"retries": retryCount,
}).Info("The Agent is online")
agentsCount = count
return nil
}

err := backoff.Retry(countAgentsFn, exp)
err := backoff.Retry(agentOnlineFn, exp)
if err != nil {
return err
}

if agentsCount != 1 {
err = fmt.Errorf("There are %.0f online agents. We expected to have exactly one", agentsCount)
log.Error(err.Error())
return err
}

return nil
}

Expand Down Expand Up @@ -268,23 +270,23 @@ func (fts *FleetTestSuite) theAgentIsUnenrolled() error {
func (fts *FleetTestSuite) theAgentIsNotListedAsOnlineInFleet() error {
log.Debug("Checking if the agent is not listed as online in Fleet")

agentsCount := 0.0
maxTimeout := 10 * time.Second
retryCount := 1

exp := e2e.GetExponentialBackOff(maxTimeout)

countAgentsFn := func() error {
count, err := countOnlineAgents()
if err != nil || count != 0 {
agentOnlineFn := func() error {
status, err := isAgentOnline(fts.Hostname)
if err != nil || status {
if err == nil {
err = fmt.Errorf("The Agent is still online")
}

log.WithFields(log.Fields{
"retry": retryCount,
"onlineAgents": count,
"elapsedTime": exp.GetElapsedTime(),
"active": status,
"elapsedTime": exp.GetElapsedTime(),
"hostname": fts.Hostname,
"retry": retryCount,
}).Warn(err.Error())

retryCount++
Expand All @@ -293,25 +295,19 @@ func (fts *FleetTestSuite) theAgentIsNotListedAsOnlineInFleet() error {
}

log.WithFields(log.Fields{
"elapsedTime": exp.GetElapsedTime(),
"onlineAgents": count,
"retries": retryCount,
"active": status,
"elapsedTime": exp.GetElapsedTime(),
"hostname": fts.Hostname,
"retries": retryCount,
}).Info("The Agent is offline")
agentsCount = count
return nil
}

err := backoff.Retry(countAgentsFn, exp)
err := backoff.Retry(agentOnlineFn, exp)
if err != nil {
return err
}

if agentsCount != 0 {
err = fmt.Errorf("There are %.0f online agents. We expected to have none", agentsCount)
log.Error(err.Error())
return err
}

return nil
}

Expand All @@ -335,18 +331,8 @@ func (fts *FleetTestSuite) theEnrollmentTokenIsRevoked() error {
"tokenID": fts.CurrentTokenID,
}).Debug("Revoking enrollment token")

revokeTokenURL := fleetEnrollmentTokenURL + "/" + fts.CurrentTokenID
deleteReq := createDefaultHTTPRequest(revokeTokenURL)

body, err := curl.Delete(deleteReq)
err := fts.removeToken()
if err != nil {
log.WithFields(log.Fields{
"token": fts.CurrentToken,
"tokenID": fts.CurrentTokenID,
"body": body,
"error": err,
"url": revokeTokenURL,
}).Error("Could revoke token")
return err
}

Expand Down Expand Up @@ -390,6 +376,24 @@ func (fts *FleetTestSuite) anAttemptToEnrollANewAgentFails() error {
return nil
}

func (fts *FleetTestSuite) removeToken() error {
revokeTokenURL := fleetEnrollmentTokenURL + "/" + fts.CurrentTokenID
deleteReq := createDefaultHTTPRequest(revokeTokenURL)

body, err := curl.Delete(deleteReq)
if err != nil {
log.WithFields(log.Fields{
"tokenID": fts.CurrentTokenID,
"body": body,
"error": err,
"url": revokeTokenURL,
}).Error("Could delete token")
return err
}

return nil
}

// checkFleetConfiguration checks that Fleet configuration is not missing
// any requirements and is read. To achieve it, a GET request is executed
func checkFleetConfiguration() error {
Expand Down Expand Up @@ -425,23 +429,6 @@ func checkFleetConfiguration() error {
return nil
}

// countOnlineAgents extracts the number of agents in the online status
// querying Fleet's agents endpoint
func countOnlineAgents() (float64, error) {
jsonResponse, err := getOnlineAgents()
if err != nil {
return 0, err
}

agentsCount := jsonResponse.Path("total").Data().(float64)

log.WithFields(log.Fields{
"count": agentsCount,
}).Debug("Online agents retrieved")

return agentsCount, nil
}

// createFleetConfiguration sends a POST request to Fleet forcing the
// recreation of the configuration
func createFleetConfiguration() error {
Expand Down Expand Up @@ -713,9 +700,9 @@ func getOnlineAgents() (*gabs.Container, error) {
r := createDefaultHTTPRequest(fleetAgentsURL)
// let's not URL encode the querystring, as it seems Kibana is not handling
// the request properly, returning an 400 Bad Request error with this message:
// [request query.page=1&perPage=20&showInactive=false]: definition for this key is missing
// [request query.page=1&perPage=20&showInactive=true]: definition for this key is missing
r.EncodeURL = false
r.QueryString = fmt.Sprintf("page=1&perPage=20&showInactive=%t", false)
r.QueryString = fmt.Sprintf("page=1&perPage=20&showInactive=%t", true)

body, err := curl.Get(r)
if err != nil {
Expand All @@ -738,3 +725,29 @@ func getOnlineAgents() (*gabs.Container, error) {

return jsonResponse, nil
}

// isAgentOnline extracts the status for an agent, identified by its hotname
// It will wuery Fleet's agents endpoint
func isAgentOnline(hostname string) (bool, error) {
jsonResponse, err := getOnlineAgents()
if err != nil {
return false, err
}

agents := jsonResponse.Path("list")

for _, agent := range agents.Children() {
agentStatus := agent.Path("active").Data().(bool)
agentHostname := agent.Path("local_metadata.host.hostname").Data().(string)
if agentHostname == hostname {
log.WithFields(log.Fields{
"active": agentStatus,
"hostname": hostname,
}).Debug("Agent status retrieved")

return agentStatus, nil
}
}

return false, fmt.Errorf("The agent '" + hostname + "' was not found in Fleet")
}
73 changes: 57 additions & 16 deletions e2e/_suites/ingest-manager/ingest-manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
package main

import (
"context"
"os"
"path"
"strings"
"time"

"github.com/cucumber/godog"
"github.com/cucumber/messages-go/v10"
"github.com/elastic/e2e-testing/cli/config"
"github.com/elastic/e2e-testing/cli/docker"
"github.com/elastic/e2e-testing/cli/services"
"github.com/elastic/e2e-testing/e2e"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -169,6 +172,14 @@ func IngestManagerFeatureContext(s *godog.Suite) {
log.WithFields(log.Fields{
"service": serviceName,
}).Debug("Service removed from compose.")

err = imts.Fleet.removeToken()
if err != nil {
log.WithFields(log.Fields{
"err": err,
"tokenID": imts.Fleet.CurrentTokenID,
}).Warn("The enrollment token could not be deleted")
}
}
})
}
Expand Down Expand Up @@ -238,22 +249,6 @@ func (imts *IngestManagerTestSuite) processStateOnTheHost(process string, state
return nil
}

func startAgent(profile string, serviceName string) error {
cmd := []string{"elastic-agent", "run"}
err := execCommandInService(profile, serviceName, cmd, true)
if err != nil {
log.WithFields(log.Fields{
"command": cmd,
"error": err,
"service": serviceName,
}).Error("Could not run the agent")

return err
}

return nil
}

func execCommandInService(profile string, serviceName string, cmds []string, detach bool) error {
serviceManager := services.NewServiceManager()

Expand Down Expand Up @@ -281,3 +276,49 @@ func execCommandInService(profile string, serviceName string, cmds []string, det

return nil
}

// we need the container name because we use the Docker Client instead of Docker Compose
func getContainerHostname(containerName string) (string, error) {
log.WithFields(log.Fields{
"containerName": containerName,
}).Debug("Retrieving container name from the Docker client")

hostname, err := docker.ExecCommandIntoContainer(context.Background(), containerName, "root", []string{"hostname"})
if err != nil {
log.WithFields(log.Fields{
"containerName": containerName,
"error": err,
}).Error("Could not retrieve container name from the Docker client")
return "", err
}

if strings.HasPrefix(hostname, "\x01\x00\x00\x00\x00\x00\x00\r") {
hostname = strings.ReplaceAll(hostname, "\x01\x00\x00\x00\x00\x00\x00\r", "")
log.WithFields(log.Fields{
"hostname": hostname,
}).Debug("Container name has been sanitized")
}

log.WithFields(log.Fields{
"containerName": containerName,
"hostname": hostname,
}).Info("Hostname retrieved from the Docker client")

return hostname, nil
}

func startAgent(profile string, serviceName string) error {
cmd := []string{"elastic-agent", "run"}
err := execCommandInService(profile, serviceName, cmd, true)
if err != nil {
log.WithFields(log.Fields{
"command": cmd,
"error": err,
"service": serviceName,
}).Error("Could not run the agent")

return err
}

return nil
}
Loading

0 comments on commit a457007

Please sign in to comment.