mirror of
https://framagit.org/framasoft/framaspace/argos.git
synced 2025-04-28 18:02:41 +02:00
✨ — Add new check type: http-to-https (fix #61)
This commit is contained in:
parent
175f605e35
commit
100171356b
7 changed files with 90 additions and 10 deletions
|
@ -5,6 +5,7 @@
|
||||||
- 💄 — Correctly show results on small screens
|
- 💄 — Correctly show results on small screens
|
||||||
- 📝💄 — Add opengraph tags to documentation site (#62)
|
- 📝💄 — Add opengraph tags to documentation site (#62)
|
||||||
- 🔨 — Add a small web server to browse documentation when developing
|
- 🔨 — Add a small web server to browse documentation when developing
|
||||||
|
- ✨ — Add new check type: http-to-https (#61)
|
||||||
|
|
||||||
## 0.4.1
|
## 0.4.1
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import json
|
||||||
import re
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
from httpx import URL
|
||||||
from jsonpointer import resolve_pointer, JsonPointerException
|
from jsonpointer import resolve_pointer, JsonPointerException
|
||||||
|
|
||||||
from argos.checks.base import (
|
from argos.checks.base import (
|
||||||
|
@ -55,6 +56,33 @@ class HTTPStatusIn(BaseCheck):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPToHTTPS(BaseCheck):
|
||||||
|
"""Checks that the HTTP to HTTPS redirection status code is the expected one."""
|
||||||
|
|
||||||
|
config = "http-to-https"
|
||||||
|
expected_cls = ExpectedStringValue
|
||||||
|
|
||||||
|
async def run(self) -> dict:
|
||||||
|
task = self.task
|
||||||
|
url = URL(task.url).copy_with(scheme="http")
|
||||||
|
response = await self.http_client.request(method="get", url=url, timeout=60)
|
||||||
|
|
||||||
|
expected_dict = json.loads(self.expected)
|
||||||
|
expected = range(300, 400)
|
||||||
|
if "range" in expected_dict:
|
||||||
|
expected = range(expected_dict["range"][0], expected_dict["range"][1])
|
||||||
|
if "value" in expected_dict:
|
||||||
|
expected = range(expected_dict["value"], expected_dict["value"] + 1)
|
||||||
|
if "list" in expected_dict:
|
||||||
|
expected = expected_dict["list"]
|
||||||
|
|
||||||
|
return self.response(
|
||||||
|
status=response.status_code in expected,
|
||||||
|
expected=self.expected,
|
||||||
|
retrieved=response.status_code,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class HTTPHeadersContain(BaseCheck):
|
class HTTPHeadersContain(BaseCheck):
|
||||||
"""Checks that response headers contains the expected headers
|
"""Checks that response headers contains the expected headers
|
||||||
(without checking their values)"""
|
(without checking their values)"""
|
||||||
|
|
|
@ -107,6 +107,21 @@ websites:
|
||||||
- headers-contain:
|
- headers-contain:
|
||||||
- "content-encoding"
|
- "content-encoding"
|
||||||
- "content-type"
|
- "content-type"
|
||||||
|
# Check that there is a HTTP to HTTPS redirection with 3xx status code
|
||||||
|
- http-to-https: true
|
||||||
|
# Check that there is a HTTP to HTTPS redirection with 301 status code
|
||||||
|
- http-to-https: 301
|
||||||
|
# Check that there is a HTTP to HTTPS redirection with a status code
|
||||||
|
# in the provided range (stop value excluded)
|
||||||
|
- http-to-https:
|
||||||
|
start: 301
|
||||||
|
stop: 308
|
||||||
|
# Check that there is a HTTP to HTTPS redirection with a status code
|
||||||
|
# in the provided list
|
||||||
|
- http-to-https:
|
||||||
|
- 301
|
||||||
|
- 302
|
||||||
|
- 307
|
||||||
- path: "/admin/"
|
- path: "/admin/"
|
||||||
checks:
|
checks:
|
||||||
# Check that the return HTTP status is one of those
|
# Check that the return HTTP status is one of those
|
||||||
|
|
|
@ -79,12 +79,26 @@ def parse_checks(value):
|
||||||
if name not in available_names:
|
if name not in available_names:
|
||||||
msg = f"Check should be one of f{available_names}. ({name} given)"
|
msg = f"Check should be one of f{available_names}. ({name} given)"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
if isinstance(expected, int):
|
if name == "http-to-https":
|
||||||
expected = str(expected)
|
if isinstance(expected, int) and expected in range(300, 400):
|
||||||
if isinstance(expected, list):
|
expected = json.dumps({"value": expected})
|
||||||
expected = json.dumps(expected)
|
elif isinstance(expected, list):
|
||||||
if isinstance(expected, dict):
|
expected = json.dumps({"list": expected})
|
||||||
expected = json.dumps(expected)
|
elif (
|
||||||
|
isinstance(expected, dict)
|
||||||
|
and "start" in expected
|
||||||
|
and "stop" in expected
|
||||||
|
):
|
||||||
|
expected = json.dumps({"range": [expected["start"], expected["stop"]]})
|
||||||
|
else:
|
||||||
|
expected = json.dumps({"range": [300, 400]})
|
||||||
|
else:
|
||||||
|
if isinstance(expected, int):
|
||||||
|
expected = str(expected)
|
||||||
|
if isinstance(expected, list):
|
||||||
|
expected = json.dumps(expected)
|
||||||
|
if isinstance(expected, dict):
|
||||||
|
expected = json.dumps(expected)
|
||||||
return (name, expected)
|
return (name, expected)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,17 +11,18 @@ These checks are the most basic ones. They simply check that the response from t
|
||||||
|
|
||||||
| Check | Description | Configuration |
|
| Check | Description | Configuration |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `status-is` | Check that the returned status code matches what you expect. | `status-is: "200"` |
|
| `status-is` | Check that the returned status code matches what you expect. | <pre><code>status-is: \"200\"</code></pre> |
|
||||||
| `status-in` | Check that the returned status code is in the list of codes you expect. | <pre><code>status-in:<br> - 200<br> - 302</code></pre> |
|
| `status-in` | Check that the returned status code is in the list of codes you expect. | <pre><code>status-in:<br> - 200<br> - 302</code></pre> |
|
||||||
| `body-contains` | Check that the returned body contains a given string. | `body-contains: "Hello world"` |
|
| `body-contains` | Check that the returned body contains a given string. | <pre><code>body-contains: "Hello world"</code></pre> |
|
||||||
| `body-like` | Check that the returned body matches a given regex. | `body-like: "Hel+o w.*"` |
|
| `body-like` | Check that the returned body matches a given regex. | <pre><code>body-like: "Hel+o w.*"</code></pre> |
|
||||||
| `headers-contain` | Check that the response contains the expected headers. | <pre><code>headers-contain:<br> - "content-encoding"<br> - "content-type"</code></pre> |
|
| `headers-contain` | Check that the response contains the expected headers. | <pre><code>headers-contain:<br> - "content-encoding"<br> - "content-type"</code></pre> |
|
||||||
| `headers-have` | Check that the response contains the expected headers with the expected value. | <pre><code>headers-have:<br> content-encoding: "gzip"<br> content-type: "text/html"</code></pre> |
|
| `headers-have` | Check that the response contains the expected headers with the expected value. | <pre><code>headers-have:<br> content-encoding: "gzip"<br> content-type: "text/html"</code></pre> |
|
||||||
| `headers-like` | Check that response headers contains the expected headers and that the values matches the provided regexes. | <pre><code>headers-like:<br> content-encoding: "gzip\|utf"<br> content-type: "text/(html\|css)"</code></pre> |
|
| `headers-like` | Check that response headers contains the expected headers and that the values matches the provided regexes. | <pre><code>headers-like:<br> content-encoding: "gzip\|utf"<br> content-type: "text/(html\|css)"</code></pre> |
|
||||||
| `json-contains` | Check that JSON response contains the expected structure. | <pre><code>json-contains:<br> - /foo/bar/0<br> - /timestamp</code></pre> |
|
| `json-contains` | Check that JSON response contains the expected structure. | <pre><code>json-contains:<br> - /foo/bar/0<br> - /timestamp</code></pre> |
|
||||||
| `json-has` | Check that JSON response contains the expected structure and values. | <pre><code>json-has:<br> /maintenance: false<br> /productname: "Nextcloud"</code></pre> |
|
| `json-has` | Check that JSON response contains the expected structure and values. | <pre><code>json-has:<br> /maintenance: false<br> /productname: "Nextcloud"</code></pre> |
|
||||||
| `json-like` | Check that JSON response contains the expected structure and that the values matches the provided regexes. | <pre><code>json-like:<br> /productname: ".\*cloud"<br> /versionstring: "29\\\\..\*"</code></pre> |
|
| `json-like` | Check that JSON response contains the expected structure and that the values matches the provided regexes. | <pre><code>json-like:<br> /productname: ".\*cloud"<br> /versionstring: "29\\\\..\*"</code></pre> |
|
||||||
| `json-is` | Check that JSON response is the exact expected JSON object. | `json-is: '{"foo": "bar", "baz": 42}'`|
|
| `json-is` | Check that JSON response is the exact expected JSON object. | <pre><code>json-is: '{"foo": "bar", "baz": 42}'</code></pre> |
|
||||||
|
| `http-to-https` | Check that the HTTP version of the domain redirects to HTTPS. Multiple choices of configuration. | <pre><code>http-to-https: true<br>http-to-https: 301<br>http-to-https:<br> start: 301<br> stop: 308<br>http-to-https:<br> - 301<br> - 302<br> - 307</code></pre> |
|
||||||
|
|
||||||
```{code-block} yaml
|
```{code-block} yaml
|
||||||
---
|
---
|
||||||
|
@ -37,6 +38,21 @@ caption: argos-config.yaml
|
||||||
- headers-contain:
|
- headers-contain:
|
||||||
- "content-encoding"
|
- "content-encoding"
|
||||||
- "content-type"
|
- "content-type"
|
||||||
|
# Check that there is a HTTP to HTTPS redirection with 3xx status code
|
||||||
|
- http-to-https: true
|
||||||
|
# Check that there is a HTTP to HTTPS redirection with 301 status code
|
||||||
|
- http-to-https: 301
|
||||||
|
# Check that there is a HTTP to HTTPS redirection with a status code
|
||||||
|
# in the provided range (stop value excluded)
|
||||||
|
- http-to-https:
|
||||||
|
start: 301
|
||||||
|
stop: 308
|
||||||
|
# Check that there is a HTTP to HTTPS redirection with a status code
|
||||||
|
# in the provided list
|
||||||
|
- http-to-https:
|
||||||
|
- 301
|
||||||
|
- 302
|
||||||
|
- 307
|
||||||
- path: "/foobar"
|
- path: "/foobar"
|
||||||
checks:
|
checks:
|
||||||
- status-in:
|
- status-in:
|
||||||
|
|
|
@ -35,6 +35,8 @@ html_sidebars = {
|
||||||
# -- Options for HTML output -------------------------------------------------
|
# -- Options for HTML output -------------------------------------------------
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||||
|
|
||||||
|
smartquotes = False
|
||||||
|
|
||||||
if "CI_JOB_ID" in environ:
|
if "CI_JOB_ID" in environ:
|
||||||
html_baseurl = "https://argos-monitoring.framasoft.org"
|
html_baseurl = "https://argos-monitoring.framasoft.org"
|
||||||
|
|
||||||
|
|
|
@ -41,3 +41,7 @@ If that's your case, you can implement the `finalize` method, and return some ex
|
||||||
# You can use the extra_arg here to determine the severity
|
# You can use the extra_arg here to determine the severity
|
||||||
return Status.SUCCESS, Severity.OK
|
return Status.SUCCESS, Severity.OK
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Document the new check
|
||||||
|
|
||||||
|
Please, document the use of the new check in `docs/checks.md` and `argos/config-example.yaml`.
|
||||||
|
|
Loading…
Reference in a new issue