Skip to content

Commit a529c26

Browse files
authored
Mend CI with resource identifiers, increased timeout. (#415)
* Increase test timeout to mend CI. Workaround until we figure out why some findings are taking a long time to show up in the ES index. * Resource identifier for process_* test suites. * Include upstream bug fix - csp-security-policies 1.2.1 * Split file_system_rules suite into more parts. * Disable automated test case for CIS K8S 4.2.3
1 parent 0d66213 commit a529c26

11 files changed

+120
-24
lines changed

.github/workflows/cloudbeat-ci.yml

+25-5
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,35 @@ jobs:
115115
include:
116116
- test-target: pre_merge
117117
- test-target: file_system_rules
118-
range: '0..15'
118+
range: '0..5'
119+
- test-target: file_system_rules
120+
range: '5..10'
121+
- test-target: file_system_rules
122+
range: '10..15'
123+
- test-target: file_system_rules
124+
range: '15..20'
125+
- test-target: file_system_rules
126+
range: '20..25'
127+
- test-target: file_system_rules
128+
range: '25..30'
129+
- test-target: file_system_rules
130+
range: '30..35'
131+
- test-target: file_system_rules
132+
range: '35..40'
133+
- test-target: file_system_rules
134+
range: '40..45'
135+
- test-target: file_system_rules
136+
range: '45..50'
137+
- test-target: file_system_rules
138+
range: '50..55'
119139
- test-target: file_system_rules
120-
range: '15..30'
140+
range: '55..60'
121141
- test-target: file_system_rules
122-
range: '30..45'
142+
range: '60..65'
123143
- test-target: file_system_rules
124-
range: '45..60'
144+
range: '65..70'
125145
- test-target: file_system_rules
126-
range: '60..'
146+
range: '70..'
127147
- test-target: k8s_object_rules
128148
range: '0..6'
129149
- test-target: k8s_object_rules

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ require (
8181
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
8282
github.com/eapache/queue v1.1.0 // indirect
8383
github.com/elastic/beats/v7 v7.0.0-alpha2.0.20220726163833-e8a0da132f1f
84-
github.com/elastic/csp-security-policies v1.2.0
84+
github.com/elastic/csp-security-policies v1.2.1
8585
github.com/ghodss/yaml v1.0.0 // indirect
8686
github.com/go-ini/ini v1.66.6 // indirect
8787
github.com/go-logr/logr v1.2.3 // indirect

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,8 @@ github.com/elastic/csp-security-policies v1.0.8 h1:Wy13f5kFlwoJLMhnhS8O5gmP3EnGE
537537
github.com/elastic/csp-security-policies v1.0.8/go.mod h1:iiMuf3IRjGmWD+a88MGen0qeYgReNd2EUqDDb+LZJGc=
538538
github.com/elastic/csp-security-policies v1.2.0 h1:o0FP379xv8xF/HUcow4cSoswtORV6CLzbri001ioI2U=
539539
github.com/elastic/csp-security-policies v1.2.0/go.mod h1:3fA3X9OiyP7IRNyacOGnWqt1eHSMVZRx7p3bmZm98oE=
540+
github.com/elastic/csp-security-policies v1.2.1 h1:exmKOXId1rT1P/SUYweuwCkuZMaxGD0/1ex8yv3JqXs=
541+
github.com/elastic/csp-security-policies v1.2.1/go.mod h1:3fA3X9OiyP7IRNyacOGnWqt1eHSMVZRx7p3bmZm98oE=
540542
github.com/elastic/e2e-testing v1.99.2-0.20220117192005-d3365c99b9c4 h1:uYT+Krd8dsvnhnLK9pe/JHZkYtXEGPfbV4Wt1JPPol0=
541543
github.com/elastic/e2e-testing v1.99.2-0.20220117192005-d3365c99b9c4/go.mod h1:UcNuf4pX/qDVNQr0zybm1NL2YoWik+jKBaINZqQCA40=
542544
github.com/elastic/elastic-agent-autodiscover v0.2.1 h1:Nbeayh3vq2FNm6xaFo34mhUdOu0EVlpj53CqCsbU0E4=

tests/commonlib/utils.py

+47
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def get_ES_evaluation(elastic_client, timeout, rule_tag, exec_timestamp,
3636
resource = event.resource.raw
3737
evaluation = event.result.evaluation
3838
except AttributeError:
39+
print('Warning: got finding with missing fields:', event)
3940
continue
4041

4142
if resource_identifier(resource):
@@ -155,3 +156,49 @@ def wait_for_cycle_completion(elastic_client, nodes: list) -> bool:
155156

156157
def is_timeout(start_time: time, timeout: int) -> bool:
157158
return time.time() - start_time > timeout
159+
160+
161+
def command_contains_arguments(command, arguments_dict):
162+
args = command.split()[1:]
163+
args_dict = {}
164+
for arg in args:
165+
key, val = arg.split('=', 1)
166+
args_dict[key] = val
167+
168+
set_dict = arguments_dict.get('set', {})
169+
unset_list = arguments_dict.get('unset', [])
170+
171+
for key, val in set_dict.items():
172+
argval = args_dict.get(key)
173+
if val != argval:
174+
return False
175+
176+
for key in unset_list:
177+
if key in args_dict:
178+
return False
179+
180+
return True
181+
182+
183+
def config_contains_arguments(config, arguments_dict):
184+
set_dict = arguments_dict.get('set', {})
185+
unset_list = arguments_dict.get('unset', [])
186+
187+
if not dict_contains(set_dict, config):
188+
return False
189+
190+
for arg in unset_list:
191+
current = config
192+
arg_set = True
193+
194+
for arg_part in arg.split('.'):
195+
if (not isinstance(current, dict)) or (arg_part not in current):
196+
arg_set = False
197+
break
198+
199+
current = current[arg_part]
200+
201+
if arg_set:
202+
return False
203+
204+
return True

tests/configuration.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
agent = Munch()
1212
agent.name = os.getenv('AGENT_NAME', 'elastic-agent')
1313
agent.namespace = os.getenv('AGENT_NAMESPACE', 'kube-system')
14-
agent.findings_timeout = 30
14+
agent.findings_timeout = 500
1515

1616
# --- Kubernetes environment definition --------------------
1717
kubernetes = Munch()

tests/product/tests/data/process/process_test_cases.py

+13-12
Original file line numberDiff line numberDiff line change
@@ -1363,18 +1363,19 @@
13631363
]
13641364

13651365
kubelet_rules = [
1366-
*skip_param_case(skip_list=[*cis_4_2_1,
1367-
*cis_4_2_2,
1368-
*cis_4_2_3,
1369-
*cis_4_2_4,
1370-
*cis_4_2_5,
1371-
*cis_4_2_6,
1372-
*cis_4_2_7,
1373-
*cis_4_2_9,
1374-
],
1375-
data_to_report=SkipReportData(
1376-
skip_reason="Dangling tests"
1377-
)),
1366+
*cis_4_2_1,
1367+
*cis_4_2_2,
1368+
*skip_param_case(skip_list=[*cis_4_2_3],
1369+
data_to_report=SkipReportData(
1370+
skip_reason="Known issue",
1371+
url_link="https://github.com/elastic/security-team/issues/5106",
1372+
url_title="security-team #5106",
1373+
)),
1374+
*cis_4_2_4,
1375+
*cis_4_2_5,
1376+
*cis_4_2_6,
1377+
*cis_4_2_7,
1378+
*cis_4_2_9,
13781379
# *cis_4_2_8, # TODO setting is not configurable via the Kubelet config file.
13791380
*cis_4_2_10,
13801381
*cis_4_2_11,

tests/product/tests/test_process_api_server_rules.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import time
88
import pytest
99

10-
from commonlib.utils import get_ES_evaluation
10+
from commonlib.utils import get_ES_evaluation, command_contains_arguments
1111
from product.tests.data.process.process_test_cases import api_server_rules
1212
from product.tests.parameters import register_params, Parameters
1313

@@ -46,11 +46,15 @@ def test_process_api_server(elastic_client,
4646
# TODO: Implement a more optimal way of waiting
4747
time.sleep(60)
4848

49+
def identifier(eval_resource):
50+
return command_contains_arguments(eval_resource.command, dictionary)
51+
4952
evaluation = get_ES_evaluation(
5053
elastic_client=elastic_client,
5154
timeout=cloudbeat_agent.findings_timeout,
5255
rule_tag=rule_tag,
5356
exec_timestamp=datetime.utcnow(),
57+
resource_identifier=identifier,
5458
)
5559

5660
assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found"

tests/product/tests/test_process_controller_manager_rules.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import time
88
import pytest
99

10-
from commonlib.utils import get_ES_evaluation
10+
from commonlib.utils import get_ES_evaluation, command_contains_arguments
1111
from product.tests.data.process.process_test_cases import controller_manager_rules
1212
from product.tests.parameters import register_params, Parameters
1313

@@ -46,11 +46,15 @@ def test_process_controller_manager(elastic_client,
4646
# TODO: Implement a more optimal way of waiting
4747
time.sleep(60)
4848

49+
def identifier(eval_resource):
50+
return command_contains_arguments(eval_resource.command, dictionary)
51+
4952
evaluation = get_ES_evaluation(
5053
elastic_client=elastic_client,
5154
timeout=cloudbeat_agent.findings_timeout,
5255
rule_tag=rule_tag,
5356
exec_timestamp=datetime.utcnow(),
57+
resource_identifier=identifier,
5458
)
5559

5660
assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found"

tests/product/tests/test_process_etcd_rules.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import time
88
import pytest
99

10-
from commonlib.utils import get_ES_evaluation
10+
from commonlib.utils import get_ES_evaluation, command_contains_arguments
1111
from product.tests.data.process.process_test_cases import etcd_rules
1212
from product.tests.parameters import register_params, Parameters
1313

@@ -46,11 +46,15 @@ def test_process_etcd(elastic_client,
4646
# TODO: Implement a more optimal way of waiting
4747
time.sleep(60)
4848

49+
def identifier(eval_resource):
50+
return command_contains_arguments(eval_resource.command, dictionary)
51+
4952
evaluation = get_ES_evaluation(
5053
elastic_client=elastic_client,
5154
timeout=cloudbeat_agent.findings_timeout,
5255
rule_tag=rule_tag,
5356
exec_timestamp=datetime.utcnow(),
57+
resource_identifier=identifier,
5458
)
5559

5660
assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found"

tests/product/tests/test_process_kubelet_rules.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import time
88
import pytest
99

10-
from commonlib.utils import get_ES_evaluation
10+
from commonlib.utils import get_ES_evaluation, config_contains_arguments
1111
from product.tests.data.process.process_test_cases import kubelet_rules
1212
from product.tests.parameters import register_params, Parameters
1313

@@ -46,11 +46,21 @@ def test_process_kubelet(elastic_client,
4646
# TODO: Implement a more optimal way of waiting
4747
time.sleep(60)
4848

49+
def identifier(eval_resource):
50+
# Needs to be done because EKS findings are showing up in vanilla K8S tests,
51+
# leading to unexpected findings structure.
52+
# See: https://github.com/elastic/security-team/issues/5107
53+
if 'external_data' not in eval_resource.keys():
54+
return False
55+
56+
return config_contains_arguments(eval_resource.external_data.config, dictionary)
57+
4958
evaluation = get_ES_evaluation(
5059
elastic_client=elastic_client,
5160
timeout=cloudbeat_agent.findings_timeout,
5261
rule_tag=rule_tag,
5362
exec_timestamp=datetime.utcnow(),
63+
resource_identifier=identifier,
5464
)
5565

5666
assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found"

tests/product/tests/test_process_scheduler_rules.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import time
88
import pytest
99

10-
from commonlib.utils import get_ES_evaluation
10+
from commonlib.utils import get_ES_evaluation, command_contains_arguments
1111
from product.tests.data.process.process_test_cases import scheduler_rules
1212
from product.tests.parameters import register_params, Parameters
1313

@@ -46,11 +46,15 @@ def test_process_scheduler(elastic_client,
4646
# TODO: Implement a more optimal way of waiting
4747
time.sleep(60)
4848

49+
def identifier(eval_resource):
50+
return command_contains_arguments(eval_resource.command, dictionary)
51+
4952
evaluation = get_ES_evaluation(
5053
elastic_client=elastic_client,
5154
timeout=cloudbeat_agent.findings_timeout,
5255
rule_tag=rule_tag,
5356
exec_timestamp=datetime.utcnow(),
57+
resource_identifier=identifier,
5458
)
5559

5660
assert evaluation is not None, f"No evaluation for rule {rule_tag} could be found"

0 commit comments

Comments
 (0)