check-opencloud-security 1.0.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.
- check_opencloud_security-1.0.1/.gitignore +247 -0
- check_opencloud_security-1.0.1/CHANGELOG.md +156 -0
- check_opencloud_security-1.0.1/LICENSE +674 -0
- check_opencloud_security-1.0.1/PKG-INFO +2375 -0
- check_opencloud_security-1.0.1/README.md +1688 -0
- check_opencloud_security-1.0.1/ansible/README.md +184 -0
- check_opencloud_security-1.0.1/check_opencloud_security.py +1442 -0
- check_opencloud_security-1.0.1/contrib/README.md +12 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/README.md +399 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/__init__.py +119 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/cli.py +184 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/config.py +278 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/data/release_schedule.json +235 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/data/vulnerabilities.json +19 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/factory.py +139 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/hardening.py +324 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/releases.py +326 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/scanner.py +1331 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/secrets.py +129 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/service.py +243 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/versions.py +581 -0
- check_opencloud_security-1.0.1/opencloud_local_scan/vulndb.py +344 -0
- check_opencloud_security-1.0.1/pyproject.toml +52 -0
- check_opencloud_security-1.0.1/secrets/README.md +37 -0
- check_opencloud_security-1.0.1/tests/__init__.py +0 -0
- check_opencloud_security-1.0.1/tests/conftest.py +27 -0
- check_opencloud_security-1.0.1/tests/fake_opencloud.py +276 -0
- check_opencloud_security-1.0.1/tests/test_config.py +294 -0
- check_opencloud_security-1.0.1/tests/test_e2e_cli.py +261 -0
- check_opencloud_security-1.0.1/tests/test_env_config.py +251 -0
- check_opencloud_security-1.0.1/tests/test_explain.py +426 -0
- check_opencloud_security-1.0.1/tests/test_local_scanner.py +365 -0
- check_opencloud_security-1.0.1/tests/test_multi_host.py +243 -0
- check_opencloud_security-1.0.1/tests/test_perfdata.py +393 -0
- check_opencloud_security-1.0.1/tests/test_rating_thresholds.py +156 -0
- check_opencloud_security-1.0.1/tests/test_release_schedule.py +393 -0
- check_opencloud_security-1.0.1/tests/test_releases.py +352 -0
- check_opencloud_security-1.0.1/tests/test_service.py +237 -0
- check_opencloud_security-1.0.1/tests/test_update_script.py +314 -0
- check_opencloud_security-1.0.1/tests/test_vulndb.py +249 -0
- check_opencloud_security-1.0.1/tests/test_waivers.py +373 -0
- check_opencloud_security-1.0.1/tests/test_webhook.py +198 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
.python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
# Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
# poetry.lock
|
|
109
|
+
# poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
# pdm.lock
|
|
116
|
+
# pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
# pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# Redis
|
|
135
|
+
*.rdb
|
|
136
|
+
*.aof
|
|
137
|
+
*.pid
|
|
138
|
+
|
|
139
|
+
# RabbitMQ
|
|
140
|
+
mnesia/
|
|
141
|
+
rabbitmq/
|
|
142
|
+
rabbitmq-data/
|
|
143
|
+
|
|
144
|
+
# ActiveMQ
|
|
145
|
+
activemq-data/
|
|
146
|
+
|
|
147
|
+
# SageMath parsed files
|
|
148
|
+
*.sage.py
|
|
149
|
+
|
|
150
|
+
# Environments
|
|
151
|
+
.env
|
|
152
|
+
.envrc
|
|
153
|
+
.venv
|
|
154
|
+
env/
|
|
155
|
+
venv/
|
|
156
|
+
ENV/
|
|
157
|
+
env.bak/
|
|
158
|
+
venv.bak/
|
|
159
|
+
|
|
160
|
+
# Spyder project settings
|
|
161
|
+
.spyderproject
|
|
162
|
+
.spyproject
|
|
163
|
+
|
|
164
|
+
# Rope project settings
|
|
165
|
+
.ropeproject
|
|
166
|
+
|
|
167
|
+
# mkdocs documentation
|
|
168
|
+
/site
|
|
169
|
+
|
|
170
|
+
# mypy
|
|
171
|
+
.mypy_cache/
|
|
172
|
+
.dmypy.json
|
|
173
|
+
dmypy.json
|
|
174
|
+
|
|
175
|
+
# Pyre type checker
|
|
176
|
+
.pyre/
|
|
177
|
+
|
|
178
|
+
# pytype static type analyzer
|
|
179
|
+
.pytype/
|
|
180
|
+
|
|
181
|
+
# Cython debug symbols
|
|
182
|
+
cython_debug/
|
|
183
|
+
|
|
184
|
+
# PyCharm
|
|
185
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
186
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
188
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
189
|
+
# .idea/
|
|
190
|
+
|
|
191
|
+
# Abstra
|
|
192
|
+
# Abstra is an AI-powered process automation framework.
|
|
193
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
194
|
+
# Learn more at https://abstra.io/docs
|
|
195
|
+
.abstra/
|
|
196
|
+
|
|
197
|
+
# Visual Studio Code
|
|
198
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
199
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
200
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
201
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
202
|
+
# .vscode/
|
|
203
|
+
# Temporary file for partial code execution
|
|
204
|
+
tempCodeRunnerFile.py
|
|
205
|
+
|
|
206
|
+
# Ruff stuff:
|
|
207
|
+
.ruff_cache/
|
|
208
|
+
|
|
209
|
+
# PyPI configuration file
|
|
210
|
+
.pypirc
|
|
211
|
+
|
|
212
|
+
# Marimo
|
|
213
|
+
marimo/_static/
|
|
214
|
+
marimo/_lsp/
|
|
215
|
+
__marimo__/
|
|
216
|
+
|
|
217
|
+
# Streamlit
|
|
218
|
+
.streamlit/secrets.toml
|
|
219
|
+
|
|
220
|
+
# --- check-opencloud-security -----------------------------------------------
|
|
221
|
+
# uv.lock is committed on purpose: it is what makes an install reproducible,
|
|
222
|
+
# and CI installs from it (see CONTRIBUTING.md).
|
|
223
|
+
!/uv.lock
|
|
224
|
+
|
|
225
|
+
/.nox
|
|
226
|
+
/.mypy_cache
|
|
227
|
+
|
|
228
|
+
# Local configuration; only the committed example is tracked.
|
|
229
|
+
/check-opencloud-security.yml
|
|
230
|
+
/check-opencloud-security.yaml
|
|
231
|
+
/config/*.yml
|
|
232
|
+
/config/*.yaml
|
|
233
|
+
!/config/*.example.yml
|
|
234
|
+
|
|
235
|
+
# Local secret files for docker-compose (only the *.example files are tracked)
|
|
236
|
+
/secrets/*
|
|
237
|
+
!/secrets/*.example
|
|
238
|
+
!/secrets/README.md
|
|
239
|
+
|
|
240
|
+
# Generated with `uv export` when a deployment tool needs it - never committed
|
|
241
|
+
/requirements.txt
|
|
242
|
+
/requirements-*.txt
|
|
243
|
+
|
|
244
|
+
# Editor state
|
|
245
|
+
.idea/
|
|
246
|
+
.vscode/
|
|
247
|
+
/.ansible/
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
New entries are added on top by the release workflow whenever the version in
|
|
9
|
+
`pyproject.toml` changes; the same entry is written to `RELEASE.md` and used as
|
|
10
|
+
the body of the GitHub release.
|
|
11
|
+
|
|
12
|
+
## [1.0.1] - 2026-08-12
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Bumped version to 1.0.1
|
|
17
|
+
- Version 1.0.0 commit
|
|
18
|
+
- Initial commit
|
|
19
|
+
|
|
20
|
+
### Documentation
|
|
21
|
+
|
|
22
|
+
- Release notes for v1.0.0 [skip ci]
|
|
23
|
+
|
|
24
|
+
## [1.0.0] - 2026-08-12
|
|
25
|
+
|
|
26
|
+
First release. A Nagios/Icinga plugin that checks an OpenCloud instance for
|
|
27
|
+
known vulnerabilities and misconfiguration. OpenCloud has no public scan API,
|
|
28
|
+
so the plugin scans entirely on its own. The ratings follow the scale of the
|
|
29
|
+
Nextcloud scan API, so that existing thresholds and dashboards keep their
|
|
30
|
+
meaning.
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- **Built-in scanner** (`opencloud_local_scan`). Reads `/status.php` and the
|
|
35
|
+
unauthenticated capabilities endpoint, evaluates security headers, and rates
|
|
36
|
+
the instance on a `0`-`5` scale. No data about the instance leaves the
|
|
37
|
+
network; hostnames, IP addresses, IPv6 and custom ports are all accepted.
|
|
38
|
+
- **OpenCloud-specific checks**: unauthenticated WebDAV, Graph and OCS
|
|
39
|
+
endpoints; exposed `opencloud.yaml`, `proxy/server.key`, the idm boltdb,
|
|
40
|
+
`.env` and `.git/config`; reachable service debug ports and `/metrics`,
|
|
41
|
+
`/config`, `/debug/pprof` handlers; enabled HTTP basic authentication;
|
|
42
|
+
version disclosure via response headers and WebFinger; directory listings;
|
|
43
|
+
maintenance mode and pending database upgrades.
|
|
44
|
+
- **Catch-all detection.** OpenCloud's single-page frontend answers unknown
|
|
45
|
+
paths with HTTP 200, so the scanner learns what a nonexistent path looks
|
|
46
|
+
like before reporting any path as exposed.
|
|
47
|
+
- **TLS inspection** with graceful degradation: verified HTTPS, then
|
|
48
|
+
unverified HTTPS with a `tlsTrusted` finding, then plain HTTP with a
|
|
49
|
+
critical `httpsAvailable` finding. Covers handshake, protocol version and
|
|
50
|
+
certificate expiry.
|
|
51
|
+
- **Correct version handling.** `/status.php` reports hardcoded legacy
|
|
52
|
+
`version`/`versionstring` fields for old sync clients; only `productversion`
|
|
53
|
+
is the real release. Instances that offer nothing else are reported as
|
|
54
|
+
`legacyVersion` instead of being rated against a version that means nothing.
|
|
55
|
+
- **Hardening reporting** derived from what the instance actually reports -
|
|
56
|
+
HSTS strength, CSP quality, basic auth, public-link password and expiry
|
|
57
|
+
enforcement, user enumeration and password policy - rather than inferred
|
|
58
|
+
from the version number.
|
|
59
|
+
- **Update check** against the OpenCloud release feed on GitHub, with `auto`,
|
|
60
|
+
`feed`, `pinned`, `bundled` and `off` modes. The offline modes and the
|
|
61
|
+
automatic fallback in `auto` keep an air-gapped or rate-limited setup
|
|
62
|
+
working.
|
|
63
|
+
- **Lifecycle-aware end-of-life detection.** OpenCloud maintains three kinds
|
|
64
|
+
of releases side by side, and each has its own support window: *rolling*
|
|
65
|
+
(a release roughly every three weeks, only the newest one receives fixes),
|
|
66
|
+
*production* (roughly every six months, kept alive with patch releases until
|
|
67
|
+
the next production release takes over) and *LTS* (a production line with
|
|
68
|
+
two years of backports). The verdict follows the published release schedule
|
|
69
|
+
in `opencloud_local_scan/data/release_schedule.json`, refreshed on release
|
|
70
|
+
and monthly by a scheduled workflow, because a flat list of major releases
|
|
71
|
+
cannot express three overlapping support windows.
|
|
72
|
+
- **`releaseType` and `lifecycle` in the result document**, reporting the
|
|
73
|
+
release line, its track, its release date, when support ends, how many days
|
|
74
|
+
are left and which release to upgrade to. The plugin prints a
|
|
75
|
+
`Release lifecycle:` line and a `support_days_left` performance value, and
|
|
76
|
+
the webhook payload carries both fields.
|
|
77
|
+
- **The update check is track aware.** A release feed only knows the newest
|
|
78
|
+
release overall, and on OpenCloud that is always a rolling one. Offering it
|
|
79
|
+
to a production or LTS instance would silently move it onto a track with a
|
|
80
|
+
three-week support window, so those instances are offered the newest release
|
|
81
|
+
of their own track instead. `UpdateInfo` carries `track` and
|
|
82
|
+
`newestRelease`, so the newest release overall is reported but not presented
|
|
83
|
+
as the thing to install.
|
|
84
|
+
- **`--release-track` declares which track an instance follows** (`rolling`,
|
|
85
|
+
`production` or `lts`). Without it a version is judged as generously as is
|
|
86
|
+
true, which is right when nobody has said otherwise but wrong for anyone
|
|
87
|
+
deliberately on the rolling track, where `7.2.3` went out of support the day
|
|
88
|
+
`7.4.0` shipped. With a declared track the version is judged on that track
|
|
89
|
+
alone, the update recommendation follows it, and the output marks the track
|
|
90
|
+
as declared rather than inferred. A version that was never published on its
|
|
91
|
+
declared track is reported with the reason rather than an empty support
|
|
92
|
+
date, and is never told to "upgrade" to an older release.
|
|
93
|
+
- **`--ignore-hardening` accepts a finding you are not going to fix.** Some
|
|
94
|
+
findings are real but not actionable in a given environment - a CSP that
|
|
95
|
+
cannot be tightened without breaking the web UI, an HSTS header owned by a
|
|
96
|
+
reverse proxy. The rating is recalculated without the waived finding, so
|
|
97
|
+
accepting one genuinely changes the grade instead of leaving the check
|
|
98
|
+
permanently yellow. The option is repeatable, takes a comma-separated list,
|
|
99
|
+
understands shell-style wildcards (`debugPort:*`), and matches hardening
|
|
100
|
+
measures, security headers, `httpsEnforced` and additional-check ids alike -
|
|
101
|
+
one option for all of them, because `basicAuthDisabled` is both a hardening
|
|
102
|
+
measure and an additional check. A waiver hides an alert, not the evidence:
|
|
103
|
+
waived findings drop out of the alert lines, the `hardenings_missing` and
|
|
104
|
+
`extra_checks_failed` metrics and the webhook payload, but stay in the
|
|
105
|
+
result document flagged with `"ignored": true` and are listed as
|
|
106
|
+
`Ignored by configuration (n): ...` in the output. Only a finding that
|
|
107
|
+
actually failed can be waived, and no waiver can clear an end-of-life
|
|
108
|
+
release.
|
|
109
|
+
- **`--debug` explains the rating.** A grade on its own is a verdict without
|
|
110
|
+
an argument, so the check can show its reasoning: where the rating started
|
|
111
|
+
(version and advisory database), which failed check capped it and by how
|
|
112
|
+
much, the final value, and the thresholds that turned it into a WARNING or
|
|
113
|
+
CRITICAL. A failed check that did *not* decide the outcome is listed too,
|
|
114
|
+
marked as such, so nothing looks quietly dropped. The same breakdown is
|
|
115
|
+
available as structured data in `ratingExplanation`, sorted by severity so
|
|
116
|
+
it does not depend on the order the checks happened to run in.
|
|
117
|
+
- **Every hardening identifier is explained.** `basicAuthDisabled` and
|
|
118
|
+
`cspWithoutUnsafeInline` say nothing to someone who has to fix them, so the
|
|
119
|
+
`opencloud_local_scan.hardening` catalogue pairs each flag with a
|
|
120
|
+
plain-language meaning, the OpenCloud environment variable that governs it
|
|
121
|
+
(`PROXY_ENABLE_BASIC_AUTH`,
|
|
122
|
+
`OC_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD`,
|
|
123
|
+
`PROXY_CSP_CONFIG_FILE_LOCATION`, ...) and a link to the documentation.
|
|
124
|
+
- **Findings that no setting can clear are recorded but never alerted on.**
|
|
125
|
+
Public-link expiry is hardcoded in OpenCloud, so `publicLinkExpirationEnforced`
|
|
126
|
+
fails on every instance and no operator can fix it; alerting on it trains
|
|
127
|
+
people to ignore the hardening line altogether. Such flags stay in the
|
|
128
|
+
result document and in `--debug`, but are kept out of the alert line, the
|
|
129
|
+
`hardenings_missing` metric and the webhook.
|
|
130
|
+
- **Advisory database** matching on the half-open range
|
|
131
|
+
`[introduced, fixed)`, accepting the native, GitHub Advisory and OSV
|
|
132
|
+
formats from the bundled file, extra files and a remote feed.
|
|
133
|
+
- **`check-opencloud-scanner`** with `scan` (one-shot JSON) and `serve`
|
|
134
|
+
(HTTP service with `/api/queue`, `/api/result/<uuid>`, `/api/requeue`,
|
|
135
|
+
`/api/scan` and `/healthz`, optional token auth and a per-host result
|
|
136
|
+
cache).
|
|
137
|
+
- **Configuration** from a YAML file, `COS_`-prefixed environment variables or
|
|
138
|
+
a secret provider (`secret://`, `file://`, `env://`, opt-in `exec://`),
|
|
139
|
+
with command line > environment > file > default precedence. This includes
|
|
140
|
+
`scanner.release_schedule` for sites with vendor support commitments that
|
|
141
|
+
differ from the public ones, `scanner.release_track` and
|
|
142
|
+
`scanner.ignore_hardenings`.
|
|
143
|
+
- **Monitoring integration**: Nagios/Icinga exit codes, performance data
|
|
144
|
+
(`rating`, `vulnerabilities`, `time`, `hardenings_missing`,
|
|
145
|
+
`extra_checks_failed`, `update_available`, `support_days_left`),
|
|
146
|
+
configurable WARNING/CRITICAL thresholds, optional hardening evaluation,
|
|
147
|
+
multi-host runs reporting the worst state, retries with exponential backoff,
|
|
148
|
+
and optional webhook notifications that never change the reported state.
|
|
149
|
+
- **Deployment**: a Docker image and `docker-compose.yml`, an Ansible role,
|
|
150
|
+
systemd service/timer and cron examples, Icinga2 and Icinga Director command
|
|
151
|
+
definitions.
|
|
152
|
+
- Documentation, a test suite covering the scanner, service, configuration,
|
|
153
|
+
release lookup, thresholds, webhooks, multi-host handling and the plugin
|
|
154
|
+
end to end as a real subprocess, and CI workflows for tests, ruff, mypy,
|
|
155
|
+
bandit, dependency review, multi-version nox runs, PyPI publishing and the
|
|
156
|
+
monthly release-schedule refresh.
|