Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solution][Endpoint] Add serverless Security project users/roles to cypress e2e test setup #167446

Merged

Conversation

paul-tavares
Copy link
Contributor

@paul-tavares paul-tavares commented Sep 27, 2023

Summary

Goal of this PR is to re-enable the serverless tests that require the login credentials for users that have the pre-defined roles from serverless assigned to them.

@kbn/test changes

  • Added support for esServerlessOptions to FTR config. Currently allows for resources to be defined
    • resources overrides were introduced in this PR
    • new FTR option will allow for testing serverless with a set of users/roles that are specific to the project type

Security Solution Plugin

  • Added esServerlessOptions to the Defend Workflows cypress configurations
  • Un-skips all serverless specific tests (now that we have support for users/roles that are specific to the Security project)
  • Changed the default username for cypress login() task to be endpoint_operations_analyst
    • Note that the previously used endpoint_operations_analyst role was also updated to match the definition used for serverless.
  • Added new common fleet_server_services cli module with reusable methods for working with fleet server, including generic startFleetServer() method
  • New CLI script: node x-pack/plugins/security_solution/scripts/endpoint/start_fleet_server.js
    • Starts a fleet server locally (via Docker) and connects it to the Kibana
    • Supports running fleet server locally for serverless as well

Serverless specific tests now passing

image

Options available with new start_fleet_server.js cli script:

node ./x-pack/plugins/security_solution/scripts/endpoint/start_fleet_server.js --help

  node x-pack/plugins/security_solution/scripts/endpoint/start_fleet_server.js

  Start fleet-server locally and connect it to Kibana/ES

  Options:
    --version           Optional. The Agent version to be used when installing fleet server.
                        Default: uses the same version as the stack (kibana). Version
                        can also be from 'SNAPSHOT'.
                        NOTE: this value will be specifically set to 'latest' when ran against
                        kibana in serverless mode.
                        Examples: 8.6.0, 8.7.0-SNAPSHOT
    --policy            Optional. The UUID of the agent policy that should be used to enroll
                        fleet-server with Kibana/ES (Default: uses existing (if found) or
                        creates a new one)
    --force             Optional. If true, then fleet-server will be started and connected to
                        kibana even if one seems to already be configured.
    --port              Optional. The port number where fleet-server will listen for requests.
                        (Default: 8220)
    --username          Optional. User name to be used for auth against elasticsearch and
                        kibana (Default: elastic).
    --password          Optional. Password associated with the username (Default: changeme)
    --kibanaUrl         Optional. The url to Kibana (Default: http://127.0.0.1:5601)
    --elasticUrl        Optional. The url to Elasticsearch (Default: http://127.0.0.1:9200)
    --verbose, -v      Log verbosely
    --debug            Log debug messages (less than verbose)
    --quiet            Only log errors
    --silent           Don't log anything
    --help             Show this message


Output of the start_fleet_server.js script

start_fleet_server.js
 info Starting Fleet Server and connecting it to Kibana
   │ info Verifying Docker is installed.
       │ info Docker version 20.10.22, build 3a2c30b
   │ info Starting a new fleet server using Docker (version: 8.11.0-SNAPSHOT)
       │ info Kibana running in serverless mode.
       │        - will install/run standalone Fleet Server
       │        - version adjusted to [latest] from [8.11.0-SNAPSHOT]
       │ info Checking status of elastic Docker network.
           │ info Using existing network.
       │ info Fleet server started
       │ info Updating Fleet with new fleet server host: https://192.168.1.87:8220
           │ info No update needed. Fleet server host URL already defined in fleet settings.
       │ info Checking if Fleet output for Elasticsearch needs to be updated
       │ info Waiting for server to register with Elasticsearch
   │ info Done. Fleet server up and running
 info 

      Container Name: dev-fleet-server.8220
      Container Id:   ba131b3dd3a2ceb7a95e40b54bde7b8498318136f6665aa076b6716760ef1906

      View running output:  docker attach ---sig-proxy=false dev-fleet-server.8220
      Shell access:         docker exec -it dev-fleet-server.8220 /bin/bash
      Kill container:       docker kill ba131b3dd3a2ceb7a95e40b54bde7b8498318136f6665aa076b6716760ef1906
        


@paul-tavares paul-tavares added release_note:skip Skip the PR/issue when compiling release notes Team:Defend Workflows “EDR Workflows” sub-team of Security Solution v8.11.0 labels Sep 27, 2023
@paul-tavares paul-tavares self-assigned this Sep 27, 2023
@@ -0,0 +1,673 @@
/*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: I will have a follow up PR to refactor the existing endpint_agent_runner utility to use this module (will also look for import's for private modules of endpoint_agent_runner). For now, most of the code here is a duplicate.

@paul-tavares paul-tavares marked this pull request as ready for review October 3, 2023 13:10
@paul-tavares paul-tavares requested a review from a team as a code owner October 3, 2023 13:10
@elasticmachine
Copy link
Contributor

Pinging @elastic/security-defend-workflows (Team:Defend Workflows)

Copy link
Contributor

@tomsonpl tomsonpl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, I've gone through the code, left a few suggestions and questions (just to help me understand, thanks in advance 👍 ).
All in all, great job as usual, thanks for doing this 👍

export const cli = async () => {
return run(
async (cliContext: RunContext) => {
const username = cliContext.flags.username as string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to cast this like that?

Copy link
Contributor Author

@paul-tavares paul-tavares Oct 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

username is not set as a string in .flags

ref:

[key: string]: undefined | boolean | string | string[];

const isServerlessEs = (await tmpEsClient.info()).version.build_flavor === 'serverless';
await waitForKibana(tmpKbnClient);

// const isServerlessEs = (await tmpEsClient.info()).version.build_flavor === 'serverless';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redundant?

if (isServerless) {
log.info(`Waiting for server to register with Elasticsearch`);

await waitForFleetServerToRegisterWithElasticsearch(kbnClient, hostname, 120000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be worth to add a log.verbose after this? as with hostToEnroll below?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is nothing here to log. The one below logs the Agent record in log.verbose()

kbnClient: KbnClient;
logger: ToolingLog;
policyId: string;
serviceToken: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe worth to specify this as string | undefined , passing an empty string may be confusing. what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same with policyId I guess ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can't be undefined for managed fleet server. I'll make them optional and will add runtime validation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, what I meant is it's either a string for manager fs or really undefined right?
But what you just did is also great, so thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct

export const startFleetServer = async ({
kbnClient,
logger,
policy,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this policy, coming from cliConfig.flags.policy - is this supposed to be supported only if used as a CLI and not CI (eg. cypress?). Which means that if provided, we do not call getOrCreateFleetServerAgentPolicyId ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct - if policy (Fleet agent policy UUID) is provided, then we don't create one automatically if one does not yet exist. It could be used from CI or CLI - it does not matter. It just provides the consumer the ability to define the specific agent policy ID to use in starting the server

- version adjusted to [latest] from [${agentVersion}]`);

agentVersion = 'latest';
await maybeCreateDockerNetwork(log);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any case where we need to additionally create the network (in serverless mode)? I understand that network is being already created with dockerized ES.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure 🤷 . I think there are some additional discussions in @patrykkopycinski 's PR about creating additional networks for Agent (hosts).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just wanted to make it consistent to make sure all docker containers are running on the same docker network

const fleetServerUrl = `https://${localhostRealIp}:${port}`;
const esURL = new URL(await getFleetElasticsearchOutputHost(kbnClient));
const containerName = `dev-fleet-server.${port}`;
const hostname = `dev-fleet-server.${port}.${Math.random().toString(32).substring(2, 6)}`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. If we don't, the host name in fleet is duplicated when we run it multiple times locally. This ensure that the host name is unique. It was also causing an issue when calling waitForHostToEnroll()


// Only fetch/create a fleet-server policy
if (!policyId && !isServerless) {
policyId = await getOrCreateFleetServerAgentPolicyId(kbnClient, logger);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can set policyId the same way as serviceToken below, it might get more readable, what do you think?

await kbnClient
.request<GetOneOutputResponse>({
method: 'PUT',
headers: { 'elastic-api-version': '2023-10-31' },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you use API_VERSIONS.public.v1 is it possible to use it also here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That const never made sense to me and I think will lead to issues. I was never really sure why a const was used. Version number will diverge at the api level (is my understanding) not the release level across all APIs

},
query: {
perPage: 100,
'elastic-api-version': '2023-10-31',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here

Copy link
Member

@jbudz jbudz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

packages/kbn-test

paul-tavares and others added 3 commits October 3, 2023 17:12
…e-serverless-tests

# Conflicts:
#	packages/kbn-test/src/es/test_es_cluster.ts
#	packages/kbn-test/src/functional_test_runner/lib/config/schema.ts
#	packages/kbn-test/src/functional_tests/lib/run_elasticsearch.ts
#	x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts
#	x-pack/test/defend_workflows_cypress/serverless_config.ts
Copy link
Contributor

@dasansol92 dasansol92 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks!

method: 'GET',
path: PACKAGE_POLICY_API_ROUTES.LIST_PATTERN,
headers: {
'elastic-api-version': '2023-10-31',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use the API_VERSIONS.public.v1 from fleet plugin?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my prior comment to @tomsonpl 's (same comment). I never really understood why we are using const's for API version

Copy link
Member

@ashokaditya ashokaditya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes. 🔥 I've not tested this locally but will take it for a spin later.

Comment on lines +32 to +33
'.lists*',
'.items*',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe these should be .lists-* and .items-*

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to leave it as is, since it matches whats defined in Project Controller (cc/ @dhurley14 )

{
names: [
'names:',
'.alerts-security*',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be .alerts-security.alerts-*

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above

@paul-tavares paul-tavares enabled auto-merge (squash) October 4, 2023 16:28
@kibana-ci
Copy link
Collaborator

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #1 / dashboard app - group 6 dashboard snapshots compare controls snapshot in dark mode
  • [job] [logs] Security Solution Cypress Tests #9 / Ransomware Detection Alerts Ransomware in Timelines Renders ransomware entries in timelines table Renders ransomware entries in timelines table

Metrics [docs]

✅ unchanged

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @paul-tavares

Copy link
Contributor

@patrykkopycinski patrykkopycinski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @paul-tavares 🙇

Copy link
Member

@dmlemeshko dmlemeshko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kbn-test changes LGTM

@paul-tavares paul-tavares merged commit 990963f into elastic:main Oct 4, 2023
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Oct 4, 2023
@paul-tavares paul-tavares deleted the task/olm-7614-enable-serverless-tests branch October 4, 2023 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting release_note:skip Skip the PR/issue when compiling release notes Team:Defend Workflows “EDR Workflows” sub-team of Security Solution v8.11.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants