2023-02-20 13:55:56 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
"""
|
|
|
|
Test collection management
|
|
|
|
"""
|
|
|
|
|
|
|
|
from http import HTTPStatus
|
|
|
|
import json
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
pytestmark = pytest.mark.docker
|
|
|
|
|
|
|
|
|
|
|
|
def test_install_two_collections(crowdsec, flavor):
|
|
|
|
"""Test installing collections at startup"""
|
|
|
|
it1 = 'crowdsecurity/apache2'
|
|
|
|
it2 = 'crowdsecurity/asterisk'
|
|
|
|
env = {
|
|
|
|
'COLLECTIONS': f'{it1} {it2}'
|
|
|
|
}
|
2023-02-28 16:49:32 +00:00
|
|
|
with crowdsec(flavor=flavor, environment=env) as cs:
|
|
|
|
cs.wait_for_http(8080, '/health', want_status=HTTPStatus.OK)
|
|
|
|
res = cs.cont.exec_run('cscli collections list -o json')
|
2023-02-20 13:55:56 +00:00
|
|
|
assert res.exit_code == 0
|
|
|
|
j = json.loads(res.output)
|
|
|
|
items = {c['name']: c for c in j['collections']}
|
|
|
|
assert items[it1]['status'] == 'enabled'
|
|
|
|
assert items[it2]['status'] == 'enabled'
|
2023-02-28 16:49:32 +00:00
|
|
|
cs.wait_for_log([
|
2023-02-20 13:55:56 +00:00
|
|
|
# f'*collections install "{it1}"*'
|
|
|
|
# f'*collections install "{it2}"*'
|
2023-11-24 14:57:32 +00:00
|
|
|
f'*Enabled collections: {it1}*',
|
|
|
|
f'*Enabled collections: {it2}*',
|
2023-02-20 13:55:56 +00:00
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
def test_disable_collection(crowdsec, flavor):
|
|
|
|
"""Test removing a pre-installed collection at startup"""
|
|
|
|
it = 'crowdsecurity/linux'
|
|
|
|
env = {
|
|
|
|
'DISABLE_COLLECTIONS': it
|
|
|
|
}
|
2023-02-28 16:49:32 +00:00
|
|
|
with crowdsec(flavor=flavor, environment=env) as cs:
|
|
|
|
cs.wait_for_log("*Starting processing data*")
|
|
|
|
cs.wait_for_http(8080, '/health', want_status=HTTPStatus.OK)
|
|
|
|
res = cs.cont.exec_run('cscli collections list -o json')
|
2023-02-20 13:55:56 +00:00
|
|
|
assert res.exit_code == 0
|
|
|
|
j = json.loads(res.output)
|
|
|
|
items = {c['name'] for c in j['collections']}
|
|
|
|
assert it not in items
|
2023-02-28 16:49:32 +00:00
|
|
|
cs.wait_for_log([
|
2023-02-20 13:55:56 +00:00
|
|
|
# f'*collections remove "{it}*",
|
|
|
|
f'*Removed symlink [[]{it}[]]*',
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
def test_install_and_disable_collection(crowdsec, flavor):
|
|
|
|
"""Declare a collection to install AND disable: disable wins"""
|
|
|
|
it = 'crowdsecurity/apache2'
|
|
|
|
env = {
|
|
|
|
'COLLECTIONS': it,
|
|
|
|
'DISABLE_COLLECTIONS': it,
|
|
|
|
}
|
2023-02-28 16:49:32 +00:00
|
|
|
with crowdsec(flavor=flavor, environment=env) as cs:
|
|
|
|
cs.wait_for_log("*Starting processing data*")
|
|
|
|
cs.wait_for_http(8080, '/health', want_status=HTTPStatus.OK)
|
|
|
|
res = cs.cont.exec_run('cscli collections list -o json')
|
2023-02-20 13:55:56 +00:00
|
|
|
assert res.exit_code == 0
|
|
|
|
j = json.loads(res.output)
|
|
|
|
items = {c['name'] for c in j['collections']}
|
|
|
|
assert it not in items
|
2023-02-28 16:49:32 +00:00
|
|
|
logs = cs.log_lines()
|
2023-02-20 13:55:56 +00:00
|
|
|
# check that there was no attempt to install
|
2023-11-24 14:57:32 +00:00
|
|
|
assert not any(f'Enabled collections: {it}' in line for line in logs)
|
2023-02-21 21:12:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
# already done in bats, prividing here as example of a somewhat complex test
|
|
|
|
def test_taint_bubble_up(crowdsec, tmp_path_factory, flavor):
|
|
|
|
coll = 'crowdsecurity/nginx'
|
|
|
|
env = {
|
|
|
|
'COLLECTIONS': f'{coll}'
|
|
|
|
}
|
|
|
|
|
2023-06-19 10:02:59 +00:00
|
|
|
with crowdsec(flavor=flavor, environment=env) as cs:
|
2023-02-28 16:49:32 +00:00
|
|
|
cs.wait_for_http(8080, '/health', want_status=HTTPStatus.OK)
|
|
|
|
res = cs.cont.exec_run('cscli collections list -o json')
|
2023-02-21 21:12:08 +00:00
|
|
|
assert res.exit_code == 0
|
|
|
|
j = json.loads(res.output)
|
|
|
|
items = {c['name']: c for c in j['collections']}
|
|
|
|
# implicit check for tainted=False
|
|
|
|
assert items[coll]['status'] == 'enabled'
|
2023-02-28 16:49:32 +00:00
|
|
|
cs.wait_for_log([
|
2023-11-24 14:57:32 +00:00
|
|
|
f'*Enabled collections: {coll}*',
|
2023-02-21 21:12:08 +00:00
|
|
|
])
|
|
|
|
|
2023-06-19 10:02:59 +00:00
|
|
|
scenario = 'crowdsecurity/http-crawl-non_statics'
|
2023-02-21 21:12:08 +00:00
|
|
|
|
2023-06-19 10:02:59 +00:00
|
|
|
# the description won't be read back, it's from the index
|
|
|
|
yq_command = f"yq -e -i '.description=\"tainted\"' /etc/crowdsec/hub/scenarios/{scenario}.yaml"
|
|
|
|
res = cs.cont.exec_run(yq_command)
|
|
|
|
assert res.exit_code == 0
|
2023-02-21 21:12:08 +00:00
|
|
|
|
2023-02-28 16:49:32 +00:00
|
|
|
res = cs.cont.exec_run(f'cscli scenarios inspect {scenario} -o json')
|
2023-02-21 21:12:08 +00:00
|
|
|
assert res.exit_code == 0
|
|
|
|
j = json.loads(res.output)
|
|
|
|
assert j['tainted'] is True
|
|
|
|
|
2023-02-28 16:49:32 +00:00
|
|
|
res = cs.cont.exec_run('cscli collections list -o json')
|
2023-02-21 21:12:08 +00:00
|
|
|
assert res.exit_code == 0
|
|
|
|
j = json.loads(res.output)
|
|
|
|
items = {c['name']: c for c in j['collections']}
|
|
|
|
assert items['crowdsecurity/nginx']['status'] == 'enabled,tainted'
|
|
|
|
assert items['crowdsecurity/base-http-scenarios']['status'] == 'enabled,tainted'
|