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

Igor api key validation #1783

Open
wants to merge 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d619871
Change the Scenarios description
IgorGuz2000 Nov 2, 2021
5619378
Merge remote-tracking branch 'upstream/master' into Igor_API_Key_vali…
IgorGuz2000 Nov 3, 2021
b85417a
adding to scenario file
IgorGuz2000 Nov 3, 2021
1fafae8
adding to scenario file
IgorGuz2000 Nov 5, 2021
48a293e
Changing Scenario Names and tag
IgorGuz2000 Nov 5, 2021
4fcda4e
Merge branch 'master' into Igor_API_Key_validation
IgorGuz2000 Nov 5, 2021
797705c
Changing step description to true
IgorGuz2000 Nov 8, 2021
425a07c
Merge remote-tracking branch 'origin/Igor_API_Key_validation' into Ig…
IgorGuz2000 Nov 8, 2021
45e4906
Removing comment out lines
IgorGuz2000 Nov 10, 2021
314f5c1
Merge branch 'master' into Igor_API_Key_validation
IgorGuz2000 Nov 11, 2021
0408187
Merge remote-tracking branch 'upstream/master' into Igor_API_Key_vali…
IgorGuz2000 Nov 11, 2021
5085a8a
Merge remote-tracking branch 'upstream/master' into Igor_API_Key_vali…
IgorGuz2000 Nov 15, 2021
c4b80e3
Merge branch 'master' into Igor_API_Key_validation
IgorGuz2000 Nov 15, 2021
491337c
Merge remote-tracking branch 'upstream/master' into Igor_API_Key_vali…
IgorGuz2000 Nov 15, 2021
41f0b52
Fixed per comments by Adam
IgorGuz2000 Nov 16, 2021
1a3e166
Merge remote-tracking branch 'origin/Igor_API_Key_validation' into Ig…
IgorGuz2000 Nov 16, 2021
add18ed
Merge remote-tracking branch 'upstream/master' into Igor_API_Key_vali…
IgorGuz2000 Nov 16, 2021
98da734
Remove unused url prefix
IgorGuz2000 Nov 16, 2021
81e3395
removed functions using gabs, and converted to struct
IgorGuz2000 Nov 18, 2021
aee3cc7
Merge branch 'master' into Igor_API_Key_validation
IgorGuz2000 Nov 18, 2021
afeee1b
Merge branch 'master' into Igor_API_Key_validation
IgorGuz2000 Nov 29, 2021
d4b6240
Merge remote-tracking branch 'upstream/master' into Igor_API_Key_vali…
IgorGuz2000 Nov 30, 2021
fb2e52a
Merge remote-tracking branch 'origin/Igor_API_Key_validation' into Ig…
IgorGuz2000 Nov 30, 2021
fafad6b
commiting changes from master
IgorGuz2000 Nov 30, 2021
80ad66e
Merge remote-tracking branch 'upstream/master' into Igor_API_Key_vali…
IgorGuz2000 Dec 1, 2021
505a7de
commiting changes from master
IgorGuz2000 Dec 1, 2021
11d2bca
Removing os from the scenarios
IgorGuz2000 Dec 1, 2021
1593067
Changing to support remote provider
IgorGuz2000 Dec 1, 2021
d15774c
Merge branch 'master' into Igor_API_Key_validation
IgorGuz2000 Dec 6, 2021
bc2b638
Merge branch 'master' into Igor_API_Key_validation
IgorGuz2000 Dec 13, 2021
d53e11d
Merge branch 'master' into Igor_API_Key_validation
IgorGuz2000 Dec 15, 2021
67f90eb
Merge branch 'master' into Igor_API_Key_validation
IgorGuz2000 Dec 17, 2021
45a2735
Merge branch 'master' into Igor_API_Key_validation
IgorGuz2000 Dec 17, 2021
8ab1871
Merge branch 'main' into Igor_API_Key_validation
IgorGuz2000 Jan 4, 2022
3a7a753
Merge branch 'main' into Igor_API_Key_validation
IgorGuz2000 Jan 11, 2022
e15903e
Merge branch 'main' into Igor_API_Key_validation
IgorGuz2000 Jan 19, 2022
b60ad26
Merge branch 'main' into Igor_API_Key_validation
IgorGuz2000 Jan 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions e2e/_suites/fleet/features/fleet_mode_agent.feature
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,13 @@ Examples: Debian
| os |
| debian |

@unenroll
@un-enroll-with-revoke
@skip:windows
Scenario Outline: Un-enrolling the <os> agent deactivates the agent
Scenario Outline: Un-enrolling with revoke the <os> agent deactivates the agent
Given a "<os>" agent is deployed to Fleet with "tar" installer
When the agent is un-enrolled
Then the agent is listed in Fleet as "inactive"
And the agent Api key invalidated "true"

@centos
Examples: Centos
Expand All @@ -90,6 +91,24 @@ Examples: Debian
| os |
| debian |

@un-enroll-without-revoke
@skip:windows
Scenario Outline: Un-enrolling without revoke the <os> deactivates the agent
Given a "<os>" agent is deployed to Fleet with "tar" installer
When the agent is un-enrolled without revoke
Then the agent is listed in Fleet as "inactive"
And the agent Api key invalidated "true"

@centos
Examples: Centos
| os |
| centos |

@debian
Examples: Debian
| os |
| debian |

@reenroll
@skip:windows
Scenario Outline: Re-enrolling the <os> agent activates the agent in Fleet
Expand Down
54 changes: 49 additions & 5 deletions e2e/_suites/fleet/fleet.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"os"
"path/filepath"
"runtime"
"strconv"

"strings"
"time"

Expand Down Expand Up @@ -62,6 +64,7 @@ type FleetTestSuite struct {
// instrumentation
currentContext context.Context
DefaultAPIKey string
AgentId string
}

// afterScenario destroys the state created by a scenario
Expand Down Expand Up @@ -104,7 +107,7 @@ func (fts *FleetTestSuite) afterScenario() {
_ = fts.deployer.Logs(fts.currentContext, agentService)
}

err := fts.unenrollHostname()
err := fts.unenrollHostname(true)
if err != nil {
manifest, _ := fts.deployer.Inspect(fts.currentContext, agentService)
log.WithFields(log.Fields{
Expand Down Expand Up @@ -167,8 +170,10 @@ func (fts *FleetTestSuite) contributeSteps(s *godog.ScenarioContext) {
s.Step(`^the host is restarted$`, fts.theHostIsRestarted)
s.Step(`^system package dashboards are listed in Fleet$`, fts.systemPackageDashboardsAreListedInFleet)
s.Step(`^the agent is un-enrolled$`, fts.theAgentIsUnenrolled)
s.Step(`^the agent is un-enrolled without revoke$`, fts.theAgentIsUnenrolledWithoutRevoke)
s.Step(`^the agent is re-enrolled on the host$`, fts.theAgentIsReenrolledOnTheHost)
s.Step(`^the enrollment token is revoked$`, fts.theEnrollmentTokenIsRevoked)
s.Step(`^the agent Api key invalidated "(([^"]*))"$`, fts.theAgentApiKeyIsInvalidated)
s.Step(`^an attempt to enroll a new agent fails$`, fts.anAttemptToEnrollANewAgentFails)
s.Step(`^the "([^"]*)" process is "([^"]*)" on the host$`, fts.processStateChangedOnTheHost)
s.Step(`^the file system Agent folder is empty$`, fts.theFileSystemAgentFolderIsEmpty)
Expand Down Expand Up @@ -713,7 +718,6 @@ func theAgentIsListedInFleetWithStatus(ctx context.Context, desiredStatus string
retryCount++
return err
}

if agentID == "" {
// the agent is not listed in Fleet
if desiredStatus == "offline" || desiredStatus == "inactive" {
Expand Down Expand Up @@ -873,7 +877,11 @@ func (fts *FleetTestSuite) systemPackageDashboardsAreListedInFleet() error {
}

func (fts *FleetTestSuite) theAgentIsUnenrolled() error {
return fts.unenrollHostname()
return fts.unenrollHostname(true)
}

func (fts *FleetTestSuite) theAgentIsUnenrolledWithoutRevoke() error {
return fts.unenrollHostname(false)
}

func (fts *FleetTestSuite) theAgentIsReenrolledOnTheHost() error {
Expand Down Expand Up @@ -1253,7 +1261,7 @@ func (fts *FleetTestSuite) anAttemptToEnrollANewAgentFails() error {
}

// unenrollHostname deletes the statuses for an existing agent, filtering by hostname
func (fts *FleetTestSuite) unenrollHostname() error {
func (fts *FleetTestSuite) unenrollHostname(revoke bool) error {
span, _ := apm.StartSpanOptions(fts.currentContext, "Unenrolling hostname", "elastic-agent.hostname.unenroll", apm.SpanOptions{
Parent: apm.SpanFromContext(fts.currentContext).TraceContext(),
})
Expand All @@ -1274,7 +1282,8 @@ func (fts *FleetTestSuite) unenrollHostname() error {
"hostname": manifest.Hostname,
}).Debug("Un-enrolling agent in Fleet")

err := fts.kibanaClient.UnEnrollAgent(fts.currentContext, agent.LocalMetadata.Host.HostName)
fts.AgentId = agent.ID
err := fts.kibanaClient.UnEnrollAgent(fts.currentContext, agent.LocalMetadata.Host.HostName, revoke)
if err != nil {
return err
}
Expand Down Expand Up @@ -1600,3 +1609,38 @@ func (fts *FleetTestSuite) theMetricsInTheDataStream(name string, set string) er

return nil
}

func (fts *FleetTestSuite) theAgentApiKeyIsInvalidated(invalidated string) error {
invalidatedBool, _ := strconv.ParseBool(invalidated)
body, err := elasticsearch.GetSecurityApiKey()
if err != nil {
log.WithFields(log.Fields{
"Error": err,
}).Error("Could not return Security Api Keys")
return err
}
if err != nil {
log.WithFields(log.Fields{
"error": err,
"responseBody": body,
}).Error("Could not parse response into JSON")
return err
}

for _, item := range body.Children() {
if item.Path("name").Data().(string) == fts.AgentId {
if item.Path("invalidated").Data().(bool) == invalidatedBool {
log.WithFields(log.Fields{
"agentId": fts.AgentId,
}).Info("The agent Api key invalidated: ", item.Path("invalidated").Data().(bool))
} else {
log.WithFields(log.Fields{
"agentId": fts.AgentId,
}).Error("The agent Api key invalidated: ", item.Path("invalidated").Data().(bool))
return errors.New("The agent Api key invalidated is should be: " + invalidated)
}
}
}

return nil
}
37 changes: 37 additions & 0 deletions internal/elasticsearch/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/Jeffail/gabs/v2"
"net"
"net/http"
"net/url"
Expand Down Expand Up @@ -369,3 +370,39 @@ func WaitForNumberOfHits(ctx context.Context, indexName string, query map[string
err := backoff.Retry(numberOfHits, exp)
return result, err
}

// GetSecurityApiKey waits for the elasticsearch SecurityApiKey to return the list of Api Keys.
func GetSecurityApiKey() (*gabs.Container, error) {

r := curl.HTTPRequest{
IgorGuz2000 marked this conversation as resolved.
Show resolved Hide resolved
URL: "http://localhost:9200/_security/api_key?",
IgorGuz2000 marked this conversation as resolved.
Show resolved Hide resolved
BasicAuthPassword: "changeme",
BasicAuthUser: "elastic",
}

response, err := curl.Get(r)
if err != nil {
log.WithFields(log.Fields{
"error": err,
"statusEndpoint": r.URL,
}).Warn("The Elasticsearch Cat Indices API is not available yet")

return nil, err
}

log.WithFields(log.Fields{
"statusEndpoint": r.URL,
}).Trace("The Elasticsearch Console SecurityApiKey API is available")

jsonParsed, err := gabs.ParseJSON([]byte(response))
IgorGuz2000 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
log.WithFields(log.Fields{
"error": err,
"responseBody": jsonParsed,
}).Error("Could not parse response into JSON")
return jsonParsed, err
}
data := jsonParsed.Path("api_keys")

return data, err
}
11 changes: 9 additions & 2 deletions internal/kibana/agents.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func (c *Client) GetAgentIDByHostname(ctx context.Context, hostname string) (str
"agentId": agent.ID,
"hostname": hostname,
}).Trace("Agent Id found")

return agent.ID, nil
}

Expand Down Expand Up @@ -245,7 +246,8 @@ func (c *Client) ListAgents(ctx context.Context) ([]Agent, error) {
}

// UnEnrollAgent unenrolls agent from fleet
func (c *Client) UnEnrollAgent(ctx context.Context, hostname string) error {
func (c *Client) UnEnrollAgent(ctx context.Context, hostname string, revoke bool) error {
var reqBody = `{}`
span, _ := apm.StartSpanOptions(ctx, "UnEnrolling Elastic Agent by hostname", "fleet.agent.un-enroll", apm.SpanOptions{
Parent: apm.SpanFromContext(ctx).TraceContext(),
})
Expand All @@ -256,7 +258,12 @@ func (c *Client) UnEnrollAgent(ctx context.Context, hostname string) error {
return err
}

reqBody := `{"revoke": true}`
if revoke == true {
reqBody = `{"revoke": true}`
}
log.WithFields(log.Fields{
"body": reqBody,
}).Info("This is the body")
IgorGuz2000 marked this conversation as resolved.
Show resolved Hide resolved
statusCode, respBody, _ := c.post(ctx, fmt.Sprintf("%s/agents/%s/unenroll", FleetAPI, agentID), []byte(reqBody))
if statusCode != 200 {
return fmt.Errorf("could not unenroll agent; API status code = %d, response body = %s", statusCode, respBody)
Expand Down
3 changes: 3 additions & 0 deletions internal/kibana/url_prefixes.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ const (

// EndpointAPI is the endpoint API
EndpointAPI = "/api/endpoint"

// ConsoleAPI is the console API
ConsoleAPI = "/api/console"
)

// getBaseURL will pull in the baseurl or an alternative host based on settings
Expand Down