Add functional tests for plugins (#941)
* Add functional tests for plugins Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com> (cherry picked from commit 1a11c87296454aac1ebbc95c06b813ae67c91819) * Update plugin dir in functional tests Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com> * Update plugin process config in func tests Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com> * Robust config replacement Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com>
This commit is contained in:
parent
078c994159
commit
e89543f725
9 changed files with 168 additions and 0 deletions
4
.github/workflows/ci_functests-install.yml
vendored
4
.github/workflows/ci_functests-install.yml
vendored
|
@ -72,6 +72,10 @@ jobs:
|
|||
run: |
|
||||
cd scripts/func_tests/
|
||||
./tests_post-install_5simulation.sh
|
||||
- name: "Test post-install plugins"
|
||||
run: |
|
||||
cd scripts/func_tests/
|
||||
sudo ./tests_post-install_7_plugin.sh
|
||||
- name: "Uninstall"
|
||||
run: sudo ./wizard.sh --uninstall
|
||||
- name: "Test post remove"
|
||||
|
|
|
@ -11,11 +11,16 @@ config_paths:
|
|||
simulation_path: /etc/crowdsec/simulation.yaml
|
||||
hub_dir: /etc/crowdsec/hub/
|
||||
index_path: /etc/crowdsec/hub/.index.json
|
||||
notification_dir: /etc/crowdsec/notifications/
|
||||
plugin_dir: /usr/local/lib/crowdsec/plugins
|
||||
crowdsec_service:
|
||||
acquisition_path: /etc/crowdsec/acquis.yaml
|
||||
parser_routines: 1
|
||||
cscli:
|
||||
output: human
|
||||
plugin_config:
|
||||
user: nobody # plugin process would be ran on behalf of this user
|
||||
group: nogroup # plugin process would be ran on behalf of this group
|
||||
db_config:
|
||||
log_level: info
|
||||
type: sqlite
|
||||
|
|
|
@ -12,6 +12,8 @@ config_paths:
|
|||
simulation_path: /etc/crowdsec/simulation.yaml
|
||||
hub_dir: /etc/crowdsec/hub/
|
||||
index_path: /etc/crowdsec/hub/.index.json
|
||||
notification_dir: /etc/crowdsec/notifications/
|
||||
plugin_dir: /usr/local/lib/crowdsec/plugins
|
||||
cscli:
|
||||
output: human
|
||||
db_config:
|
||||
|
@ -21,6 +23,9 @@ db_config:
|
|||
flush:
|
||||
max_items: 5000
|
||||
max_age: 7d
|
||||
plugin_config:
|
||||
user: nobody # plugin process would be ran on behalf of this user
|
||||
group: nogroup # plugin process would be ran on behalf of this group
|
||||
api:
|
||||
client:
|
||||
insecure_skip_verify: false
|
||||
|
|
|
@ -11,6 +11,8 @@ config_paths:
|
|||
simulation_path: /etc/crowdsec/simulation.yaml
|
||||
hub_dir: /etc/crowdsec/hub/
|
||||
index_path: /etc/crowdsec/hub/.index.json
|
||||
notification_dir: /etc/crowdsec/notifications/
|
||||
plugin_dir: /usr/local/lib/crowdsec/plugins
|
||||
crowdsec_service:
|
||||
acquisition_path: /etc/crowdsec/acquis.yaml
|
||||
parser_routines: 1
|
||||
|
@ -23,6 +25,9 @@ db_config:
|
|||
flush:
|
||||
max_items: 5000
|
||||
max_age: 7d
|
||||
plugin_config:
|
||||
user: nobody # plugin process would be ran on behalf of this user
|
||||
group: nogroup # plugin process would be ran on behalf of this group
|
||||
api:
|
||||
client:
|
||||
insecure_skip_verify: false
|
||||
|
|
|
@ -11,11 +11,16 @@ config_paths:
|
|||
simulation_path: /etc/crowdsec/simulation.yaml
|
||||
hub_dir: /etc/crowdsec/hub/
|
||||
index_path: /etc/crowdsec/hub/.index.json
|
||||
notification_dir: /etc/crowdsec/notifications/
|
||||
plugin_dir: /usr/local/lib/crowdsec/plugins
|
||||
crowdsec_service:
|
||||
acquisition_path: /etc/crowdsec/acquis.yaml
|
||||
parser_routines: 1
|
||||
cscli:
|
||||
output: human
|
||||
plugin_config:
|
||||
user: nobody # plugin process would be ran on behalf of this user
|
||||
group: nogroup # plugin process would be ran on behalf of this group
|
||||
db_config:
|
||||
log_level: info
|
||||
type: sqlite
|
||||
|
|
25
scripts/func_tests/config/http.yaml
Normal file
25
scripts/func_tests/config/http.yaml
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Don't change this
|
||||
type: http
|
||||
|
||||
name: http_default # this must match with the registered plugin in the profile
|
||||
log_level: info # Options include: trace, debug, info, warn, error, off
|
||||
|
||||
format: | # This template receives list of models.Alert objects. The request body would contain this.
|
||||
{{.|toJson}}
|
||||
|
||||
url: http://localhost:9999 # plugin will make requests to this url. Eg value https://www.example.com/
|
||||
|
||||
method: POST # eg either of "POST", "GET", "PUT" and other http verbs is valid value.
|
||||
|
||||
# headers:
|
||||
# Authorization: token 0x64312313
|
||||
|
||||
# skip_tls_verification: # either true or false. Default is false
|
||||
|
||||
# group_wait: # duration to wait collecting alerts before sending to this plugin, eg "30s"
|
||||
|
||||
group_threshold: 2 # if alerts exceed this, then the plugin will be sent the message. eg "10"
|
||||
|
||||
# max_retry: # number of tries to attempt to send message to plugins in case of error.
|
||||
|
||||
# timeout: # duration to wait for response from plugin before considering this attempt a failure. eg "10s"
|
12
scripts/func_tests/config/profiles.yaml
Normal file
12
scripts/func_tests/config/profiles.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
name: default_ip_remediation
|
||||
#debug: true
|
||||
filters:
|
||||
- 1==1
|
||||
decisions:
|
||||
- type: ban
|
||||
duration: 4h
|
||||
notifications:
|
||||
# - slack_default # Set the webhook in /etc/crowdsec/notifications/slack.yaml before enabling this.
|
||||
# - splunk_default # Set the splunk url and token in /etc/crowdsec/notifications/splunk.yaml before enabling this.
|
||||
- http_default # Set the required http parameters in /etc/crowdsec/notifications/http.yaml before enabling this.
|
||||
on_success: break
|
26
scripts/func_tests/mock_http_server.py
Normal file
26
scripts/func_tests/mock_http_server.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
import json
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
|
||||
class RequestHandler(BaseHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
request_path = self.path
|
||||
request_body = self.rfile.read(int(self.headers['Content-Length']))
|
||||
request_body = json.loads(request_body)
|
||||
log = {
|
||||
"path": request_path,
|
||||
"status": 200,
|
||||
"request_body": request_body,
|
||||
}
|
||||
print(json.dumps(log))
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type','application/json')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps({}).encode())
|
||||
return
|
||||
|
||||
def log_message(self, format, *args):
|
||||
return
|
||||
|
||||
if __name__ == "__main__" :
|
||||
server = HTTPServer(('', 9999), RequestHandler)
|
||||
server.serve_forever()
|
81
scripts/func_tests/tests_post-install_7_plugin.sh
Executable file
81
scripts/func_tests/tests_post-install_7_plugin.sh
Executable file
|
@ -0,0 +1,81 @@
|
|||
#! /usr/bin/env bash
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
source tests_base.sh
|
||||
|
||||
MOCK_SERVER_PID=""
|
||||
|
||||
function backup () {
|
||||
cat /etc/crowdsec/profiles.yaml > ./backup_profiles.yaml
|
||||
cat /etc/crowdsec/notifications/http.yaml > ./backup_http.yaml
|
||||
}
|
||||
|
||||
function restore_backup () {
|
||||
cat ./backup_profiles.yaml > /etc/crowdsec/profiles.yaml
|
||||
cat ./backup_http.yaml > /etc/crowdsec/notifications/http.yaml
|
||||
}
|
||||
|
||||
function clear_backup() {
|
||||
rm ./backup_profiles.yaml
|
||||
rm ./backup_http.yaml
|
||||
}
|
||||
|
||||
function modify_config() {
|
||||
cp ./config/http.yaml /etc/crowdsec/notifications/http.yaml
|
||||
cp ./config/profiles.yaml /etc/crowdsec/profiles.yaml
|
||||
systemctl restart crowdsec
|
||||
}
|
||||
|
||||
function setup_tests() {
|
||||
backup
|
||||
cscli decisions delete --all
|
||||
modify_config
|
||||
python3 -u mock_http_server.py > mock_http_server_logs.log &
|
||||
MOCK_SERVER_PID=$!
|
||||
}
|
||||
|
||||
function cleanup_tests() {
|
||||
restore_backup
|
||||
clear_backup
|
||||
kill -9 $MOCK_SERVER_PID
|
||||
rm mock_http_server_logs.log
|
||||
systemctl restart crowdsec
|
||||
}
|
||||
|
||||
function run_tests() {
|
||||
log_line_count=$(cat mock_http_server_logs.log | wc -l)
|
||||
if [[ $log_line_count -ne "0" ]] ; then
|
||||
cleanup_tests
|
||||
fail "expected 0 log lines fom mock http server before adding decisions"
|
||||
fi
|
||||
cscli decisions add --ip 1.2.3.4 --duration 30s
|
||||
cscli decisions add --ip 1.2.3.5 --duration 30s
|
||||
sleep 5
|
||||
log_line_count=$(cat mock_http_server_logs.log | wc -l)
|
||||
if [[ $log_line_count -ne "1" ]] ; then
|
||||
cleanup_tests
|
||||
fail "expected 1 log line from http server"
|
||||
fi
|
||||
|
||||
total_alerts=$(cat mock_http_server_logs.log | jq .request_body | jq length)
|
||||
if [[ $total_alerts -ne "2" ]] ; then
|
||||
cleanup_tests
|
||||
fail "expected to receive 2 alerts in the request body from plugin"
|
||||
fi
|
||||
|
||||
first_received_ip=$(cat mock_http_server_logs.log | jq -r .request_body[0].decisions[0].value)
|
||||
if [[ $first_received_ip != "1.2.3.4" ]] ; then
|
||||
cleanup_tests
|
||||
fail "expected to receive IP 1.2.3.4 as value of first decision"
|
||||
fi
|
||||
|
||||
second_received_ip=$(cat mock_http_server_logs.log | jq -r .request_body[1].decisions[0].value)
|
||||
if [[ $second_received_ip != "1.2.3.5" ]] ; then
|
||||
cleanup_tests
|
||||
fail "expected to receive IP 1.2.3.5 as value of second decision"
|
||||
fi
|
||||
}
|
||||
|
||||
setup_tests
|
||||
run_tests
|
||||
cleanup_tests
|
Loading…
Reference in a new issue