secator 0.11.0__tar.gz → 0.15.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of secator might be problematic. Click here for more details.
- {secator-0.11.0 → secator-0.15.1}/.docker/Dockerfile.alpine +2 -0
- {secator-0.11.0 → secator-0.15.1}/.docker/Dockerfile.arch +2 -2
- {secator-0.11.0 → secator-0.15.1}/.docker/Dockerfile.debian +2 -2
- {secator-0.11.0 → secator-0.15.1}/.docker/Dockerfile.kali +2 -2
- {secator-0.11.0 → secator-0.15.1}/.docker/Dockerfile.osx +2 -2
- {secator-0.11.0 → secator-0.15.1}/.docker/Dockerfile.ubuntu +2 -2
- {secator-0.11.0 → secator-0.15.1}/CHANGELOG.md +60 -0
- {secator-0.11.0 → secator-0.15.1}/PKG-INFO +11 -3
- {secator-0.11.0 → secator-0.15.1}/README.md +9 -2
- {secator-0.11.0 → secator-0.15.1}/pyproject.toml +2 -1
- {secator-0.11.0 → secator-0.15.1}/secator/cli.py +201 -68
- {secator-0.11.0 → secator-0.15.1}/secator/config.py +3 -2
- secator-0.15.1/secator/configs/profiles/aggressive.yaml +8 -0
- secator-0.15.1/secator/configs/profiles/default.yaml +8 -0
- secator-0.15.1/secator/configs/profiles/insane.yaml +8 -0
- secator-0.15.1/secator/configs/profiles/paranoid.yaml +8 -0
- secator-0.15.1/secator/configs/profiles/polite.yaml +8 -0
- secator-0.15.1/secator/configs/profiles/sneaky.yaml +8 -0
- secator-0.15.1/secator/configs/profiles/tor.yaml +5 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/host_recon.yaml +11 -2
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/url_dirsearch.yaml +5 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/url_params_fuzz.yaml +2 -0
- {secator-0.11.0 → secator-0.15.1}/secator/decorators.py +56 -31
- {secator-0.11.0 → secator-0.15.1}/secator/definitions.py +5 -4
- {secator-0.11.0 → secator-0.15.1}/secator/installer.py +38 -17
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/stat.py +3 -0
- {secator-0.11.0 → secator-0.15.1}/secator/report.py +2 -2
- {secator-0.11.0 → secator-0.15.1}/secator/runners/_base.py +37 -6
- {secator-0.11.0 → secator-0.15.1}/secator/runners/_helpers.py +13 -2
- {secator-0.11.0 → secator-0.15.1}/secator/runners/command.py +5 -1
- {secator-0.11.0 → secator-0.15.1}/secator/runners/scan.py +1 -0
- {secator-0.11.0 → secator-0.15.1}/secator/runners/task.py +1 -0
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/_categories.py +19 -16
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/arjun.py +13 -3
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/bbot.py +33 -4
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/bup.py +4 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/cariddi.py +17 -4
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/dalfox.py +4 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/dirsearch.py +4 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/dnsx.py +5 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/dnsxbrute.py +4 -1
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/feroxbuster.py +5 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/ffuf.py +5 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/fping.py +4 -1
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/gau.py +5 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/gf.py +4 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/gitleaks.py +7 -4
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/gospider.py +5 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/grype.py +5 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/h8mail.py +4 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/httpx.py +6 -3
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/katana.py +6 -3
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/maigret.py +4 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/mapcidr.py +4 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/msfconsole.py +8 -6
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/naabu.py +10 -5
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/nmap.py +2 -0
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/nuclei.py +18 -10
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/searchsploit.py +8 -3
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/subfinder.py +5 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/testssl.py +6 -4
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/trivy.py +6 -3
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/wafw00f.py +4 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/wpprobe.py +4 -2
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/wpscan.py +8 -4
- {secator-0.11.0 → secator-0.15.1}/secator/template.py +12 -0
- {secator-0.11.0 → secator-0.15.1}/secator/utils.py +18 -13
- {secator-0.11.0 → secator-0.15.1}/secator/utils_test.py +9 -3
- {secator-0.11.0 → secator-0.15.1}/tests/integration/inputs.py +2 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/test_helpers.py +15 -1
- {secator-0.11.0 → secator-0.15.1}/tests/integration/test_tasks.py +15 -3
- {secator-0.11.0 → secator-0.15.1}/tests/unit/test_tasks.py +3 -3
- secator-0.11.0/secator/configs/profiles/aggressive.yaml +0 -7
- secator-0.11.0/secator/configs/profiles/default.yaml +0 -9
- secator-0.11.0/secator/configs/profiles/stealth.yaml +0 -7
- {secator-0.11.0 → secator-0.15.1}/.docker/build_all.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/.dockerignore +0 -0
- {secator-0.11.0 → secator-0.15.1}/.flake8 +0 -0
- {secator-0.11.0 → secator-0.15.1}/.gitignore +0 -0
- {secator-0.11.0 → secator-0.15.1}/CONTRIBUTING.md +0 -0
- {secator-0.11.0 → secator-0.15.1}/Dockerfile +0 -0
- {secator-0.11.0 → secator-0.15.1}/LICENSE +0 -0
- {secator-0.11.0 → secator-0.15.1}/SECURITY.md +0 -0
- {secator-0.11.0 → secator-0.15.1}/cloudbuild.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/helm/.helmignore +0 -0
- {secator-0.11.0 → secator-0.15.1}/helm/Chart.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/helm/templates/redis-service.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/helm/templates/redis.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/helm/templates/secator-manager.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/helm/templates/secator-worker.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/helm/values.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/download_cves.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/install.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/install_asciinema.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/install_go.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/install_ruby.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/msf/exploit_cve.rc +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/msf/ftp_anonymous.rc +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/msf/ftp_version.rc +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/msf/ftp_vsftpd_234_backdoor.rc +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/msf/redis.rc +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/stories/STORY.md +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/stories/aliases.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/stories/demo.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/stories/fmt.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/stories/input.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/stories/pipe.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/scripts/stories/short_demo.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/.gitignore +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/celery.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/celery_signals.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/celery_utils.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/profiles/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/scans/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/scans/domain.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/scans/host.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/scans/network.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/scans/subdomain.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/scans/url.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/cidr_recon.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/code_scan.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/subdomain_recon.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/url_bypass.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/url_crawl.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/url_fuzz.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/url_nuclei.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/url_vuln.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/user_hunt.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/configs/workflows/wordpress.yaml +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/exporters/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/exporters/_base.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/exporters/console.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/exporters/csv.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/exporters/gdrive.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/exporters/json.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/exporters/table.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/exporters/txt.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/hooks/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/hooks/gcs.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/hooks/mongodb.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/_base.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/certificate.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/error.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/exploit.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/info.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/ip.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/port.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/progress.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/record.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/state.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/subdomain.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/tag.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/target.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/url.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/user_account.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/vulnerability.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/output_types/warning.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/rich.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/runners/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/runners/celery.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/runners/workflow.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/scans/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/serializers/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/serializers/dataclass.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/serializers/json.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/serializers/regex.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/tasks/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/thread.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/secator/workflows/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/fixtures/h8mail_breach.txt +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/fixtures/ls.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/fixtures/msfconsole_input.rc +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/fixtures/nmap_output.xml +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/outputs.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/setup.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/teardown.sh +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/test_addons.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/test_celery.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/test_scans.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/test_worker.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/test_workflows.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/wordlist.txt +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/wordlist_dns.txt +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/wordpress_toolbox/Dockerfile +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/integration/wordpress_toolbox/Makefile +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/performance/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/performance/loadtester.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/performance/test_worker.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/unit/__init__.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/unit/test_celery.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/unit/test_cli.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/unit/test_command.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/unit/test_config.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/unit/test_offline.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/unit/test_runners.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/unit/test_scans.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/unit/test_serializers.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/unit/test_tasks_categories.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/unit/test_template.py +0 -0
- {secator-0.11.0 → secator-0.15.1}/tests/unit/test_utils.py +0 -0
|
@@ -21,6 +21,7 @@ RUN pipx install --pip-args="--no-cache-dir" . && \
|
|
|
21
21
|
|
|
22
22
|
FROM python:3.12-alpine
|
|
23
23
|
ARG flavor=full
|
|
24
|
+
ARG build_from_source=false
|
|
24
25
|
ENV TERM="xterm-256color"
|
|
25
26
|
ENV PATH="${PATH}:/root/.local/bin"
|
|
26
27
|
ENV GOBIN="/root/.local/bin"
|
|
@@ -29,5 +30,6 @@ RUN apk add --no-cache \
|
|
|
29
30
|
flock \
|
|
30
31
|
pipx \
|
|
31
32
|
sudo
|
|
33
|
+
RUN if [ "$build_from_source" = "true" ]; then secator config set security.force_source_install 1; fi
|
|
32
34
|
RUN if [ "$flavor" != "lite" ]; then secator install tools --cleanup --fail-fast; fi
|
|
33
35
|
ENTRYPOINT ["secator"]
|
|
@@ -31,6 +31,6 @@ RUN pipx install . && \
|
|
|
31
31
|
secator install addons mongodb && \
|
|
32
32
|
secator install addons redis && \
|
|
33
33
|
secator install addons dev
|
|
34
|
-
RUN secator config set security.force_source_install
|
|
35
|
-
RUN secator install tools --cleanup --fail-fast
|
|
34
|
+
RUN if [ "$build_from_source" = "true" ]; then secator config set security.force_source_install 1; fi
|
|
35
|
+
RUN if [ "$flavor" != "lite" ]; then secator install tools --cleanup --fail-fast; fi
|
|
36
36
|
ENTRYPOINT ["secator"]
|
|
@@ -33,6 +33,6 @@ RUN pipx install . && \
|
|
|
33
33
|
secator install addons redis && \
|
|
34
34
|
secator install addons dev
|
|
35
35
|
RUN secator install langs go
|
|
36
|
-
RUN secator config set security.force_source_install
|
|
37
|
-
RUN secator install tools --cleanup --fail-fast
|
|
36
|
+
RUN if [ "$build_from_source" = "true" ]; then secator config set security.force_source_install 1; fi
|
|
37
|
+
RUN if [ "$flavor" != "lite" ]; then secator install tools --cleanup --fail-fast; fi
|
|
38
38
|
ENTRYPOINT ["secator"]
|
|
@@ -32,6 +32,6 @@ RUN pipx install . && \
|
|
|
32
32
|
secator install addons mongodb && \
|
|
33
33
|
secator install addons redis && \
|
|
34
34
|
secator install addons dev
|
|
35
|
-
RUN secator config set security.force_source_install
|
|
36
|
-
RUN secator install tools --cleanup --fail-fast
|
|
35
|
+
RUN if [ "$build_from_source" = "true" ]; then secator config set security.force_source_install 1; fi
|
|
36
|
+
RUN if [ "$flavor" != "lite" ]; then secator install tools --cleanup --fail-fast; fi
|
|
37
37
|
ENTRYPOINT ["secator"]
|
|
@@ -35,6 +35,6 @@ RUN pipx install . && \
|
|
|
35
35
|
secator install addons mongodb && \
|
|
36
36
|
secator install addons redis && \
|
|
37
37
|
secator install addons dev
|
|
38
|
-
RUN secator config set security.force_source_install
|
|
39
|
-
RUN secator install tools --cleanup --fail-fast
|
|
38
|
+
RUN if [ "$build_from_source" = "true" ]; then secator config set security.force_source_install 1; fi
|
|
39
|
+
RUN if [ "$flavor" != "lite" ]; then secator install tools --cleanup --fail-fast; fi
|
|
40
40
|
ENTRYPOINT ["secator"]
|
|
@@ -32,6 +32,6 @@ RUN pipx install . && \
|
|
|
32
32
|
secator install addons mongodb && \
|
|
33
33
|
secator install addons redis && \
|
|
34
34
|
secator install addons dev
|
|
35
|
-
RUN secator config set security.force_source_install
|
|
36
|
-
RUN secator install tools --cleanup --fail-fast
|
|
35
|
+
RUN if [ "$build_from_source" = "true" ]; then secator config set security.force_source_install 1; fi
|
|
36
|
+
RUN if [ "$flavor" != "lite" ]; then secator install tools --cleanup --fail-fast; fi
|
|
37
37
|
ENTRYPOINT ["secator"]
|
|
@@ -1,5 +1,65 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.15.0](https://github.com/freelabz/secator/compare/v0.14.0...v0.15.0) (2025-05-04)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* improve cli usage and add multi input types ([#609](https://github.com/freelabz/secator/issues/609)) ([b850914](https://github.com/freelabz/secator/commit/b8509141e62dfd72e0b4f15c2b9b5466089e9818))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* installer issue on non-standard distribs ([#613](https://github.com/freelabz/secator/issues/613)) ([194e911](https://github.com/freelabz/secator/commit/194e911b420fcbb0feec3b563a098a3f36cc09cd))
|
|
14
|
+
|
|
15
|
+
## [0.14.0](https://github.com/freelabz/secator/compare/v0.13.0...v0.14.0) (2025-04-30)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* add support for profiles ([#532](https://github.com/freelabz/secator/issues/532)) ([6f499b7](https://github.com/freelabz/secator/commit/6f499b72ec18dddde717e00318be4e2b53cc0478))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* **cli:** restore --unified option, delete port_scan workflow ([#606](https://github.com/freelabz/secator/issues/606)) ([6dc647d](https://github.com/freelabz/secator/commit/6dc647d7205d15faa1c675485af441549d798118))
|
|
26
|
+
|
|
27
|
+
## [0.13.0](https://github.com/freelabz/secator/compare/v0.12.0...v0.13.0) (2025-04-29)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Features
|
|
31
|
+
|
|
32
|
+
* **core:** restore default task opts, improve workflows ([#560](https://github.com/freelabz/secator/issues/560)) ([4849d44](https://github.com/freelabz/secator/commit/4849d44448f52529380a6d9163a1b4db54114958))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Bug Fixes
|
|
36
|
+
|
|
37
|
+
* use distro.like() instead of distro.id() ([#604](https://github.com/freelabz/secator/issues/604)) ([15157d4](https://github.com/freelabz/secator/commit/15157d433a0c60292ed91bb26f513a10f15924c2))
|
|
38
|
+
|
|
39
|
+
## [0.12.0](https://github.com/freelabz/secator/compare/v0.11.1...v0.12.0) (2025-04-24)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### Features
|
|
43
|
+
|
|
44
|
+
* add --show option to display yaml ([#601](https://github.com/freelabz/secator/issues/601)) ([8edffe9](https://github.com/freelabz/secator/commit/8edffe9f879bb7a99a7e5fead1a18dbf6da5d140))
|
|
45
|
+
* **arjun:** add --disable-redirects opts ([#598](https://github.com/freelabz/secator/issues/598)) ([17618c7](https://github.com/freelabz/secator/commit/17618c7ca647536207a96ce2c235ec5227db2cef))
|
|
46
|
+
* **workflows:** improve url params fuzz workflow ([#597](https://github.com/freelabz/secator/issues/597)) ([38fa1bc](https://github.com/freelabz/secator/commit/38fa1bcd76c9c6dbe0bc85c9c8c707ae642b9830))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
### Bug Fixes
|
|
50
|
+
|
|
51
|
+
* better options overrides for CLI ([#596](https://github.com/freelabz/secator/issues/596)) ([74e256b](https://github.com/freelabz/secator/commit/74e256b434d36f1e16390f8d06571e726517f5ce))
|
|
52
|
+
* worker quiet option ([#602](https://github.com/freelabz/secator/issues/602)) ([9b2c084](https://github.com/freelabz/secator/commit/9b2c08458e3412a89ec39547a728a26885fe1162))
|
|
53
|
+
|
|
54
|
+
## [0.11.1](https://github.com/freelabz/secator/compare/v0.11.0...v0.11.1) (2025-04-23)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### Bug Fixes
|
|
58
|
+
|
|
59
|
+
* fping ret code ([#593](https://github.com/freelabz/secator/issues/593)) ([f2d0982](https://github.com/freelabz/secator/commit/f2d0982ea665a08d24afd3f80c8f976811daa397))
|
|
60
|
+
* ghsa lookups, startup file downloads ([#592](https://github.com/freelabz/secator/issues/592)) ([021bf11](https://github.com/freelabz/secator/commit/021bf11b6cd7d9ecb5dd95b45d6411d1feeeb86c))
|
|
61
|
+
* wordlist dynamic download ([#595](https://github.com/freelabz/secator/issues/595)) ([9a859ae](https://github.com/freelabz/secator/commit/9a859ae8f391bb73263b356ef166f5685683c30f))
|
|
62
|
+
|
|
3
63
|
## [0.11.0](https://github.com/freelabz/secator/compare/v0.10.0...v0.11.0) (2025-04-22)
|
|
4
64
|
|
|
5
65
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: secator
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.1
|
|
4
4
|
Summary: The pentester's swiss knife.
|
|
5
5
|
Project-URL: Homepage, https://github.com/freelabz/secator
|
|
6
6
|
Project-URL: Issues, https://github.com/freelabz/secator/issues
|
|
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
21
21
|
Requires-Python: >=3.8
|
|
22
22
|
Requires-Dist: beautifulsoup4<=5
|
|
23
23
|
Requires-Dist: celery<6
|
|
24
|
+
Requires-Dist: click<8.2.0
|
|
24
25
|
Requires-Dist: cpe<2
|
|
25
26
|
Requires-Dist: distro<2
|
|
26
27
|
Requires-Dist: dotmap<2
|
|
@@ -82,7 +83,7 @@ Description-Content-Type: text/markdown
|
|
|
82
83
|
<a href="https://pypi.org/project/secator/"><img src="https://img.shields.io/pypi/dm/secator"></a>
|
|
83
84
|
<a href="https://twitter.com/freelabz"><img src="https://img.shields.io/twitter/follow/freelabz.svg?logo=twitter"></a>
|
|
84
85
|
<a href="https://youtube.com/@FreeLabz"><img src="https://img.shields.io/youtube/channel/subscribers/UCu-F6SpU0h2NP18zBBP04cw?style=social&label=Subscribe%20%40FreeLabz"></a>
|
|
85
|
-
|
|
86
|
+
<a href="https://discord.gg/nyHjC2aTrq"><img src="https://img.shields.io/discord/695645237418131507.svg?logo=discord"></a>
|
|
86
87
|
</p>
|
|
87
88
|
|
|
88
89
|
|
|
@@ -91,7 +92,8 @@ Description-Content-Type: text/markdown
|
|
|
91
92
|
<a href="#supported-commands">Supported commands</a> •
|
|
92
93
|
<a href="#install-secator">Installation</a> •
|
|
93
94
|
<a href="#usage">Usage</a> •
|
|
94
|
-
<a href="https://docs.freelabz.com">Documentation</a>
|
|
95
|
+
<a href="https://docs.freelabz.com">Documentation</a> •
|
|
96
|
+
<a href="https://discord.gg/nyHjC2aTrq">Join us on Discord !</a>
|
|
95
97
|
</p>
|
|
96
98
|
|
|
97
99
|
`secator` is a task and workflow runner used for security assessments. It supports dozens of well-known security tools
|
|
@@ -122,6 +124,11 @@ and it is designed to improve productivity for pentesters and security researche
|
|
|
122
124
|
|
|
123
125
|
| Name | Description | Category |
|
|
124
126
|
|---------------------------------------------------------------|--------------------------------------------------------------------------------|-----------------|
|
|
127
|
+
| [arjun](https://github.com/s0md3v/Arjun) | HTTP Parameter Discovery Suite. | |
|
|
128
|
+
| [gitleaks](https://github.com/gitleaks/gitleaks) | Tool for detecting secrets like passwords, API keys, tokens, etc. | |
|
|
129
|
+
| [testssl](https://github.com/testssl/testssl.sh) | SSL/TLS security scanner, including ciphers, protocols and cryptographic flaws.| |
|
|
130
|
+
| [wafw00f](https://github.com/EnableSecurity/wafw00f) | Web Application Firewall Fingerprinting tool. | |
|
|
131
|
+
| [wpprobe](https://github.com/Chocapikk/wpprobe) | Fast wordpress plugin enumeration tool. | |
|
|
125
132
|
| [httpx](https://github.com/projectdiscovery/httpx) | Fast HTTP prober. | `http` |
|
|
126
133
|
| [cariddi](https://github.com/edoardottt/cariddi) | Fast crawler and endpoint secrets / api keys / tokens matcher. | `http/crawler` |
|
|
127
134
|
| [gau](https://github.com/lc/gau) | Offline URL crawler (Alien Vault, The Wayback Machine, Common Crawl, URLScan). | `http/crawler` |
|
|
@@ -139,6 +146,7 @@ and it is designed to improve productivity for pentesters and security researche
|
|
|
139
146
|
| [naabu](https://github.com/projectdiscovery/naabu) | Fast port discovery tool. | `recon/port` |
|
|
140
147
|
| [maigret](https://github.com/soxoj/maigret) | Hunt for user accounts across many websites. | `recon/user` |
|
|
141
148
|
| [gf](https://github.com/tomnomnom/gf) | A wrapper around grep to avoid typing common patterns. | `tagger` |
|
|
149
|
+
| [trivy](https://github.com/aquasecurity/trivy) | Comprehensive and versatile security scanner. | `vuln` |
|
|
142
150
|
| [grype](https://github.com/anchore/grype) | A vulnerability scanner for container images and filesystems. | `vuln/code` |
|
|
143
151
|
| [dalfox](https://github.com/hahwul/dalfox) | Powerful XSS scanning tool and parameter analyzer. | `vuln/http` |
|
|
144
152
|
| [msfconsole](https://docs.rapid7.com/metasploit/msf-overview) | CLI to access and work with the Metasploit Framework. | `vuln/http` |
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<a href="https://pypi.org/project/secator/"><img src="https://img.shields.io/pypi/dm/secator"></a>
|
|
13
13
|
<a href="https://twitter.com/freelabz"><img src="https://img.shields.io/twitter/follow/freelabz.svg?logo=twitter"></a>
|
|
14
14
|
<a href="https://youtube.com/@FreeLabz"><img src="https://img.shields.io/youtube/channel/subscribers/UCu-F6SpU0h2NP18zBBP04cw?style=social&label=Subscribe%20%40FreeLabz"></a>
|
|
15
|
-
|
|
15
|
+
<a href="https://discord.gg/nyHjC2aTrq"><img src="https://img.shields.io/discord/695645237418131507.svg?logo=discord"></a>
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
18
|
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
<a href="#supported-commands">Supported commands</a> •
|
|
22
22
|
<a href="#install-secator">Installation</a> •
|
|
23
23
|
<a href="#usage">Usage</a> •
|
|
24
|
-
<a href="https://docs.freelabz.com">Documentation</a>
|
|
24
|
+
<a href="https://docs.freelabz.com">Documentation</a> •
|
|
25
|
+
<a href="https://discord.gg/nyHjC2aTrq">Join us on Discord !</a>
|
|
25
26
|
</p>
|
|
26
27
|
|
|
27
28
|
`secator` is a task and workflow runner used for security assessments. It supports dozens of well-known security tools
|
|
@@ -52,6 +53,11 @@ and it is designed to improve productivity for pentesters and security researche
|
|
|
52
53
|
|
|
53
54
|
| Name | Description | Category |
|
|
54
55
|
|---------------------------------------------------------------|--------------------------------------------------------------------------------|-----------------|
|
|
56
|
+
| [arjun](https://github.com/s0md3v/Arjun) | HTTP Parameter Discovery Suite. | |
|
|
57
|
+
| [gitleaks](https://github.com/gitleaks/gitleaks) | Tool for detecting secrets like passwords, API keys, tokens, etc. | |
|
|
58
|
+
| [testssl](https://github.com/testssl/testssl.sh) | SSL/TLS security scanner, including ciphers, protocols and cryptographic flaws.| |
|
|
59
|
+
| [wafw00f](https://github.com/EnableSecurity/wafw00f) | Web Application Firewall Fingerprinting tool. | |
|
|
60
|
+
| [wpprobe](https://github.com/Chocapikk/wpprobe) | Fast wordpress plugin enumeration tool. | |
|
|
55
61
|
| [httpx](https://github.com/projectdiscovery/httpx) | Fast HTTP prober. | `http` |
|
|
56
62
|
| [cariddi](https://github.com/edoardottt/cariddi) | Fast crawler and endpoint secrets / api keys / tokens matcher. | `http/crawler` |
|
|
57
63
|
| [gau](https://github.com/lc/gau) | Offline URL crawler (Alien Vault, The Wayback Machine, Common Crawl, URLScan). | `http/crawler` |
|
|
@@ -69,6 +75,7 @@ and it is designed to improve productivity for pentesters and security researche
|
|
|
69
75
|
| [naabu](https://github.com/projectdiscovery/naabu) | Fast port discovery tool. | `recon/port` |
|
|
70
76
|
| [maigret](https://github.com/soxoj/maigret) | Hunt for user accounts across many websites. | `recon/user` |
|
|
71
77
|
| [gf](https://github.com/tomnomnom/gf) | A wrapper around grep to avoid typing common patterns. | `tagger` |
|
|
78
|
+
| [trivy](https://github.com/aquasecurity/trivy) | Comprehensive and versatile security scanner. | `vuln` |
|
|
72
79
|
| [grype](https://github.com/anchore/grype) | A vulnerability scanner for container images and filesystems. | `vuln/code` |
|
|
73
80
|
| [dalfox](https://github.com/hahwul/dalfox) | Powerful XSS scanning tool and parameter analyzer. | `vuln/http` |
|
|
74
81
|
| [msfconsole](https://docs.rapid7.com/metasploit/msf-overview) | CLI to access and work with the Metasploit Framework. | `vuln/http` |
|
|
@@ -4,7 +4,7 @@ build-backend = 'hatchling.build'
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = 'secator'
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.15.1"
|
|
8
8
|
authors = [{ name = 'FreeLabz', email = 'sales@freelabz.com' }]
|
|
9
9
|
readme = 'README.md'
|
|
10
10
|
description = "The pentester's swiss knife."
|
|
@@ -48,6 +48,7 @@ dependencies = [
|
|
|
48
48
|
'requests < 3',
|
|
49
49
|
'rich < 14',
|
|
50
50
|
'rich-click < 1.7',
|
|
51
|
+
'click < 8.2.0',
|
|
51
52
|
'psutil < 7',
|
|
52
53
|
'retry < 1',
|
|
53
54
|
'tldextract < 6',
|
|
@@ -36,8 +36,9 @@ click.rich_click.USE_RICH_MARKUP = True
|
|
|
36
36
|
ALL_TASKS = discover_tasks()
|
|
37
37
|
ALL_WORKFLOWS = [t for t in TEMPLATES if t.type == 'workflow']
|
|
38
38
|
ALL_SCANS = [t for t in TEMPLATES if t.type == 'scan']
|
|
39
|
+
ALL_PROFILES = [t for t in TEMPLATES if t.type == 'profile']
|
|
39
40
|
FINDING_TYPES_LOWER = [c.__name__.lower() for c in FINDING_TYPES]
|
|
40
|
-
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
|
|
41
|
+
CONTEXT_SETTINGS = dict(help_option_names=['-h', '-help', '--help'])
|
|
41
42
|
|
|
42
43
|
|
|
43
44
|
#-----#
|
|
@@ -46,15 +47,16 @@ CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
|
|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
@click.group(cls=OrderedGroup, invoke_without_command=True, context_settings=CONTEXT_SETTINGS)
|
|
49
|
-
@click.option('--version', '-version', is_flag=True, default=False)
|
|
50
|
+
@click.option('--version', '-version', '-v', is_flag=True, default=False)
|
|
51
|
+
@click.option('--quiet', '-quiet', '-q', is_flag=True, default=False)
|
|
50
52
|
@click.pass_context
|
|
51
|
-
def cli(ctx, version):
|
|
53
|
+
def cli(ctx, version, quiet):
|
|
52
54
|
"""Secator CLI."""
|
|
53
55
|
ctx.obj = {
|
|
54
56
|
'piped_input': S_ISFIFO(os.fstat(0).st_mode),
|
|
55
57
|
'piped_output': not sys.stdout.isatty()
|
|
56
58
|
}
|
|
57
|
-
if not ctx.obj['piped_output']:
|
|
59
|
+
if not ctx.obj['piped_output'] and not quiet:
|
|
58
60
|
console.print(ASCII, highlight=False)
|
|
59
61
|
if ctx.invoked_subcommand is None:
|
|
60
62
|
if version:
|
|
@@ -67,11 +69,16 @@ def cli(ctx, version):
|
|
|
67
69
|
# TASK #
|
|
68
70
|
#------#
|
|
69
71
|
|
|
70
|
-
@cli.group(aliases=['x', 't'])
|
|
72
|
+
@cli.group(aliases=['x', 't'], invoke_without_command=True)
|
|
73
|
+
@click.option('--list', '-list', is_flag=True, default=False)
|
|
71
74
|
@click.pass_context
|
|
72
|
-
def task(ctx):
|
|
75
|
+
def task(ctx, list=False):
|
|
73
76
|
"""Run a task."""
|
|
74
|
-
|
|
77
|
+
if list:
|
|
78
|
+
print("\n".join(sorted([t.__name__ for t in ALL_TASKS])))
|
|
79
|
+
return
|
|
80
|
+
if ctx.invoked_subcommand is None:
|
|
81
|
+
ctx.get_help()
|
|
75
82
|
|
|
76
83
|
|
|
77
84
|
for cls in ALL_TASKS:
|
|
@@ -83,11 +90,16 @@ for cls in ALL_TASKS:
|
|
|
83
90
|
#----------#
|
|
84
91
|
|
|
85
92
|
|
|
86
|
-
@cli.group(cls=OrderedGroup, aliases=['w'])
|
|
93
|
+
@cli.group(cls=OrderedGroup, aliases=['w'], invoke_without_command=True)
|
|
94
|
+
@click.option('--list', '-list', is_flag=True, default=False)
|
|
87
95
|
@click.pass_context
|
|
88
|
-
def workflow(ctx):
|
|
96
|
+
def workflow(ctx, list=False):
|
|
89
97
|
"""Run a workflow."""
|
|
90
|
-
|
|
98
|
+
if list:
|
|
99
|
+
print("\n".join(sorted([t.name for t in ALL_WORKFLOWS])))
|
|
100
|
+
return
|
|
101
|
+
if ctx.invoked_subcommand is None:
|
|
102
|
+
ctx.get_help()
|
|
91
103
|
|
|
92
104
|
|
|
93
105
|
for config in sorted(ALL_WORKFLOWS, key=lambda x: x['name']):
|
|
@@ -98,17 +110,41 @@ for config in sorted(ALL_WORKFLOWS, key=lambda x: x['name']):
|
|
|
98
110
|
# SCAN #
|
|
99
111
|
#------#
|
|
100
112
|
|
|
101
|
-
@cli.group(cls=OrderedGroup, aliases=['s'])
|
|
113
|
+
@cli.group(cls=OrderedGroup, aliases=['s'], invoke_without_command=True)
|
|
114
|
+
@click.option('--list', '-list', is_flag=True, default=False)
|
|
102
115
|
@click.pass_context
|
|
103
|
-
def scan(ctx):
|
|
116
|
+
def scan(ctx, list=False):
|
|
104
117
|
"""Run a scan."""
|
|
105
|
-
|
|
118
|
+
if list:
|
|
119
|
+
print("\n".join(sorted([t.name for t in ALL_SCANS])))
|
|
120
|
+
return
|
|
121
|
+
if ctx.invoked_subcommand is None:
|
|
122
|
+
ctx.get_help()
|
|
106
123
|
|
|
107
124
|
|
|
108
125
|
for config in sorted(ALL_SCANS, key=lambda x: x['name']):
|
|
109
126
|
register_runner(scan, config)
|
|
110
127
|
|
|
111
128
|
|
|
129
|
+
@cli.group(aliases=['p'])
|
|
130
|
+
@click.pass_context
|
|
131
|
+
def profile(ctx):
|
|
132
|
+
"""Show profiles"""
|
|
133
|
+
pass
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@profile.command('list')
|
|
137
|
+
def profile_list():
|
|
138
|
+
table = Table()
|
|
139
|
+
table.add_column("Profile name", style="bold gold3")
|
|
140
|
+
table.add_column("Description", overflow='fold')
|
|
141
|
+
table.add_column("Options", overflow='fold')
|
|
142
|
+
for profile in ALL_PROFILES:
|
|
143
|
+
opts_str = ','.join(f'{k}={v}' for k, v in profile.opts.items())
|
|
144
|
+
table.add_row(profile.name, profile.description, opts_str)
|
|
145
|
+
console.print(table)
|
|
146
|
+
|
|
147
|
+
|
|
112
148
|
#--------#
|
|
113
149
|
# WORKER #
|
|
114
150
|
#--------#
|
|
@@ -119,7 +155,7 @@ for config in sorted(ALL_SCANS, key=lambda x: x['name']):
|
|
|
119
155
|
@click.option('-r', '--reload', is_flag=True, help='Autoreload Celery on code changes.')
|
|
120
156
|
@click.option('-Q', '--queue', type=str, default='', help='Listen to a specific queue.')
|
|
121
157
|
@click.option('-P', '--pool', type=str, default='eventlet', help='Pool implementation.')
|
|
122
|
-
@click.option('--quiet', is_flag=True, help='Quiet mode.')
|
|
158
|
+
@click.option('--quiet', is_flag=True, default=False, help='Quiet mode.')
|
|
123
159
|
@click.option('--loglevel', type=str, default='INFO', help='Log level.')
|
|
124
160
|
@click.option('--check', is_flag=True, help='Check if Celery worker is alive.')
|
|
125
161
|
@click.option('--dev', is_flag=True, help='Start a worker in dev mode (celery multi).')
|
|
@@ -669,7 +705,7 @@ def report_show(report_query, output, runner_type, time_delta, type, query, work
|
|
|
669
705
|
all_results.extend(runner.results)
|
|
670
706
|
continue
|
|
671
707
|
report = Report(runner, title=f"Consolidated report - {current}", exporters=exporters)
|
|
672
|
-
report.build(extractors=extractors if not unified else [])
|
|
708
|
+
report.build(extractors=extractors if not unified else [], dedupe=unified)
|
|
673
709
|
file_date = get_file_date(path)
|
|
674
710
|
runner_name = data['info']['name']
|
|
675
711
|
console.print(
|
|
@@ -747,7 +783,7 @@ def report_list(workspace, runner_type, time_delta):
|
|
|
747
783
|
@report.command('export')
|
|
748
784
|
@click.argument('json_path', type=str)
|
|
749
785
|
@click.option('--output-folder', '-of', type=str)
|
|
750
|
-
@click.option('-output', '-o', type=str)
|
|
786
|
+
@click.option('-output', '-o', type=str, required=True)
|
|
751
787
|
def report_export(json_path, output_folder, output):
|
|
752
788
|
with open(json_path, 'r') as f:
|
|
753
789
|
data = loads_dataclass(f.read())
|
|
@@ -860,13 +896,21 @@ def health(json, debug, strict):
|
|
|
860
896
|
import json as _json
|
|
861
897
|
print(_json.dumps(status))
|
|
862
898
|
|
|
899
|
+
# Print errors and warnings
|
|
900
|
+
error = False
|
|
901
|
+
for tool, info in status['tools'].items():
|
|
902
|
+
if not info['installed']:
|
|
903
|
+
console.print(Warning(message=f'{tool} is not installed.'))
|
|
904
|
+
error = True
|
|
905
|
+
elif info['outdated']:
|
|
906
|
+
message = (
|
|
907
|
+
f'{tool} is outdated (current:{info["version"]}, latest:{info["latest_version"]}).'
|
|
908
|
+
f' Run `secator install tools {tool}` to update it.'
|
|
909
|
+
)
|
|
910
|
+
console.print(Warning(message=message))
|
|
911
|
+
|
|
863
912
|
# Strict mode
|
|
864
913
|
if strict:
|
|
865
|
-
error = False
|
|
866
|
-
for tool, info in status['tools'].items():
|
|
867
|
-
if not info['installed']:
|
|
868
|
-
console.print(Error(message=f'{tool} is not installed.'))
|
|
869
|
-
error = True
|
|
870
914
|
if error:
|
|
871
915
|
sys.exit(1)
|
|
872
916
|
console.print(Info(message='Strict healthcheck passed !'))
|
|
@@ -1061,16 +1105,27 @@ def install_tools(cmds, cleanup, fail_fast):
|
|
|
1061
1105
|
if CONFIG.offline_mode:
|
|
1062
1106
|
console.print(Error(message='Cannot run this command in offline mode.'))
|
|
1063
1107
|
return
|
|
1108
|
+
tools = []
|
|
1064
1109
|
if cmds is not None:
|
|
1065
1110
|
cmds = cmds.split(',')
|
|
1066
|
-
|
|
1111
|
+
for cmd in cmds:
|
|
1112
|
+
if '==' in cmd:
|
|
1113
|
+
cmd, version = tuple(cmd.split('=='))
|
|
1114
|
+
else:
|
|
1115
|
+
cmd, version = cmd, None
|
|
1116
|
+
cls = next((cls for cls in ALL_TASKS if cls.__name__ == cmd), None)
|
|
1117
|
+
if cls:
|
|
1118
|
+
if version:
|
|
1119
|
+
cls.install_version = version
|
|
1120
|
+
tools.append(cls)
|
|
1121
|
+
else:
|
|
1122
|
+
console.print(Warning(message=f'Tool {cmd} is not supported or inexistent.'))
|
|
1067
1123
|
else:
|
|
1068
1124
|
tools = ALL_TASKS
|
|
1069
1125
|
tools.sort(key=lambda x: x.__name__)
|
|
1070
1126
|
return_code = 0
|
|
1071
1127
|
if not tools:
|
|
1072
|
-
|
|
1073
|
-
console.print(Error(message=f'No tools found for {cmd_str}.'))
|
|
1128
|
+
console.print(Error(message='No tools found for installing.'))
|
|
1074
1129
|
return
|
|
1075
1130
|
for ix, cls in enumerate(tools):
|
|
1076
1131
|
# with console.status(f'[bold yellow][{ix + 1}/{len(tools)}] Installing {cls.__name__} ...'):
|
|
@@ -1140,7 +1195,7 @@ def update(all):
|
|
|
1140
1195
|
cmd = cls.cmd.split(' ')[0]
|
|
1141
1196
|
version_flag = cls.get_version_flag()
|
|
1142
1197
|
info = get_version_info(cmd, version_flag, cls.install_github_handle)
|
|
1143
|
-
if not info['installed'] or info['
|
|
1198
|
+
if not info['installed'] or info['outdated'] or not info['latest_version']:
|
|
1144
1199
|
# with console.status(f'[bold yellow]Installing {cls.__name__} ...'):
|
|
1145
1200
|
status = ToolInstaller.install(cls)
|
|
1146
1201
|
if not status.is_ok():
|
|
@@ -1375,73 +1430,151 @@ def performance(tasks, workflows, scans, test):
|
|
|
1375
1430
|
@test.command()
|
|
1376
1431
|
@click.argument('name', type=str)
|
|
1377
1432
|
@click.option('--verbose', '-v', is_flag=True, default=False, help='Print verbose output')
|
|
1378
|
-
|
|
1379
|
-
|
|
1433
|
+
@click.option('--check', '-c', is_flag=True, default=False, help='Check task semantics only (no unit + integration tests)') # noqa: E501
|
|
1434
|
+
def task(name, verbose, check):
|
|
1435
|
+
"""Test a single task for semantics errors, and run unit + integration tests."""
|
|
1436
|
+
console.print(f'[bold gold3]:wrench: Testing task {name} ...[/]')
|
|
1380
1437
|
task = [task for task in ALL_TASKS if task.__name__ == name]
|
|
1381
1438
|
warnings = []
|
|
1439
|
+
errors = []
|
|
1382
1440
|
exit_code = 0
|
|
1383
1441
|
|
|
1384
1442
|
# Check if task is correctly registered
|
|
1385
|
-
check_error(task, 'Check task is registered', 'Task is not registered. Make sure there is no syntax errors in the task class definition.', warnings) # noqa: E501
|
|
1386
1443
|
task = task[0]
|
|
1387
1444
|
task_name = task.__name__
|
|
1388
1445
|
|
|
1446
|
+
# Check task command is set
|
|
1447
|
+
check_test(
|
|
1448
|
+
task.cmd,
|
|
1449
|
+
'Check task command is set (cls.cmd)',
|
|
1450
|
+
'Task has no cmd attribute.',
|
|
1451
|
+
errors
|
|
1452
|
+
)
|
|
1453
|
+
if errors:
|
|
1454
|
+
sys.exit(0)
|
|
1455
|
+
|
|
1389
1456
|
# Run install
|
|
1390
|
-
console.print(f'\n[bold gold3]:wrench: Running install tests for task {name} ...[/]') if verbose else None
|
|
1391
1457
|
cmd = f'secator install tools {task_name}'
|
|
1392
1458
|
ret_code = Command.execute(cmd, name='install', quiet=not verbose, cwd=ROOT_FOLDER)
|
|
1393
1459
|
version_info = task.get_version_info()
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1460
|
+
if verbose:
|
|
1461
|
+
console.print(f'Version info:\n{version_info}')
|
|
1462
|
+
status = version_info['status']
|
|
1463
|
+
check_test(
|
|
1464
|
+
version_info['installed'],
|
|
1465
|
+
'Check task is installed',
|
|
1466
|
+
'Failed to install command. Fix your installation command.',
|
|
1467
|
+
errors
|
|
1468
|
+
)
|
|
1469
|
+
check_test(
|
|
1470
|
+
any(cmd for cmd in [task.install_pre, task.install_cmd, task.install_github_handle]),
|
|
1471
|
+
'Check task installation command is defined',
|
|
1472
|
+
'Task has no installation command. Please define one or more of the following class attributes: `install_pre`, `install_cmd`, `install_post`, `install_github_handle`.', # noqa: E501
|
|
1473
|
+
errors
|
|
1474
|
+
)
|
|
1475
|
+
check_test(
|
|
1476
|
+
version_info['version'],
|
|
1477
|
+
'Check task version can be fetched',
|
|
1478
|
+
'Failed to detect current version. Consider updating your `version_flag` class attribute.',
|
|
1479
|
+
warnings,
|
|
1480
|
+
warn=True
|
|
1481
|
+
)
|
|
1482
|
+
check_test(
|
|
1483
|
+
status != 'latest unknown',
|
|
1484
|
+
'Check latest version',
|
|
1485
|
+
'Failed to detect latest version.',
|
|
1486
|
+
warnings,
|
|
1487
|
+
warn=True
|
|
1488
|
+
)
|
|
1489
|
+
check_test(
|
|
1490
|
+
not version_info['outdated'],
|
|
1491
|
+
'Check task version is up to date',
|
|
1492
|
+
f'Task is not up to date (current version: {version_info["version"]}, latest: {version_info["latest_version"]}). Consider updating your `install_version` class attribute.', # noqa: E501
|
|
1493
|
+
warnings,
|
|
1494
|
+
warn=True
|
|
1495
|
+
)
|
|
1397
1496
|
|
|
1398
1497
|
# Run task-specific tests
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1498
|
+
check_test(
|
|
1499
|
+
task.__doc__,
|
|
1500
|
+
'Check task description is set (cls.__doc__)',
|
|
1501
|
+
'Task has no description (class docstring).',
|
|
1502
|
+
errors
|
|
1503
|
+
)
|
|
1504
|
+
check_test(
|
|
1505
|
+
task.input_types,
|
|
1506
|
+
'Check task input type is set (cls.input_type)',
|
|
1507
|
+
'Task has no input_type attribute.',
|
|
1508
|
+
warnings,
|
|
1509
|
+
warn=True
|
|
1510
|
+
)
|
|
1511
|
+
check_test(
|
|
1512
|
+
task.output_types,
|
|
1513
|
+
'Check task output types is set (cls.output_types)',
|
|
1514
|
+
'Task has no output_types attribute. Consider setting some so that secator can load your task outputs.',
|
|
1515
|
+
warnings,
|
|
1516
|
+
warn=True
|
|
1517
|
+
)
|
|
1518
|
+
check_test(
|
|
1519
|
+
task.install_version,
|
|
1520
|
+
'Check task install_version is set (cls.install_version)',
|
|
1521
|
+
'Task has no install_version attribute. Consider setting it to pin the tool version and ensure it does not break in the future.', # noqa: E501
|
|
1522
|
+
warnings,
|
|
1523
|
+
warn=True
|
|
1524
|
+
)
|
|
1525
|
+
|
|
1526
|
+
if not check:
|
|
1527
|
+
|
|
1528
|
+
# Run unit tests
|
|
1529
|
+
cmd = f'secator test unit --tasks {name}'
|
|
1530
|
+
ret_code = run_test(cmd, exit=False, verbose=verbose)
|
|
1531
|
+
check_test(
|
|
1532
|
+
ret_code == 0,
|
|
1533
|
+
'Check unit tests pass',
|
|
1534
|
+
'Unit tests failed.',
|
|
1535
|
+
errors
|
|
1536
|
+
)
|
|
1537
|
+
|
|
1538
|
+
# Run integration tests
|
|
1539
|
+
cmd = f'secator test integration --tasks {name}'
|
|
1540
|
+
ret_code = run_test(cmd, exit=False, verbose=verbose)
|
|
1541
|
+
check_test(
|
|
1542
|
+
ret_code == 0,
|
|
1543
|
+
'Check integration tests pass',
|
|
1544
|
+
'Integration tests failed.',
|
|
1545
|
+
errors
|
|
1546
|
+
)
|
|
1428
1547
|
|
|
1429
1548
|
# Exit with exit code
|
|
1430
|
-
exit_code = 1 if len(
|
|
1549
|
+
exit_code = 1 if len(errors) > 0 else 0
|
|
1431
1550
|
if exit_code == 0:
|
|
1432
|
-
console.print(f':tada: Task {name} tests passed !
|
|
1551
|
+
console.print(f':tada: Task {name} tests passed !', style='bold green')
|
|
1433
1552
|
else:
|
|
1434
|
-
console.print(
|
|
1553
|
+
console.print('\n[bold gold3]Errors:[/]')
|
|
1554
|
+
for error in errors:
|
|
1555
|
+
console.print(error)
|
|
1556
|
+
console.print(Error(message=f'Task {name} tests failed. Please fix the issues above.'))
|
|
1435
1557
|
|
|
1558
|
+
if warnings:
|
|
1559
|
+
console.print('\n[bold gold3]Warnings:[/]')
|
|
1560
|
+
for warning in warnings:
|
|
1561
|
+
console.print(warning)
|
|
1562
|
+
|
|
1563
|
+
console.print("\n")
|
|
1436
1564
|
sys.exit(exit_code)
|
|
1437
1565
|
|
|
1438
1566
|
|
|
1439
|
-
def
|
|
1567
|
+
def check_test(condition, message, fail_message, results=[], warn=False):
|
|
1440
1568
|
console.print(f'[bold magenta]:zap: {message} ...[/]', end='')
|
|
1441
1569
|
if not condition:
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1570
|
+
if not warn:
|
|
1571
|
+
error = Error(message=fail_message)
|
|
1572
|
+
console.print(' [bold red]FAILED[/]', style='dim')
|
|
1573
|
+
results.append(error)
|
|
1574
|
+
else:
|
|
1575
|
+
warning = Warning(message=fail_message)
|
|
1576
|
+
console.print(' [bold yellow]WARNING[/]', style='dim')
|
|
1577
|
+
results.append(warning)
|
|
1445
1578
|
else:
|
|
1446
1579
|
console.print(' [bold green]OK[/]', style='dim')
|
|
1447
1580
|
return True
|