diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index d4bb2cb..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_templates/repository.html b/docs/_templates/repository.html new file mode 100644 index 0000000..bf84c44 --- /dev/null +++ b/docs/_templates/repository.html @@ -0,0 +1,8 @@ + + + + + + framasoft/argos + + \ No newline at end of file diff --git a/docs/checks.md b/docs/checks.md index 4a910c9..0f96724 100644 --- a/docs/checks.md +++ b/docs/checks.md @@ -2,8 +2,44 @@ At its core, argos runs checks and return the results to the service. Here are the implemented checks, with a description of what they do and how to configure them. +## Simple checks + +These checks are the most basic ones. They simply check that the response from the service matches what you expect. + | Check | Description | Configuration | | --- | --- | --- | | `status-is` | Check that the returned status code matches what you expect. | `status-is: "200"` | | `body-contains` | Check that the returned body contains a given string. | `body-contains: "Hello world"` | -| `ssl-certificate-expiration` | Check that the SSL certificate expires in more than X days. | `ssl-certificate-expiration: "30d"` | \ No newline at end of file + +```{code-block} yaml +--- +caption: config.yaml +--- +- domain: "https://example.org" + paths: + - path: "/" + checks: + - status-is: 200 + - body-contains: "Hello world" +``` + +## SSL certificate expiration + + Checks that the SSL certificate will not expire soon. You need to define the thresholds in the configuration, and set the `on-check` option to enable the check. + + +```{code-block} yaml +--- +caption: config.yaml +--- +ssl: + thresholds: + - "1d": critical + - "5d": warning + +- domain: "https://example.org" + paths: + - path: "/" + checks: + - ssl-certificate-expiration: "on-check" +``` \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 266955b..a8f285b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,15 +14,19 @@ release = "0.0.1" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration -extensions = [ - "myst_parser", - "sphinx_design", -] +extensions = ["myst_parser", "sphinx_design", "sphinxcontrib.mermaid"] myst_enable_extensions = ["colon_fence"] templates_path = ["_templates"] exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +mermaid_params = ['--theme', 'forest'] +html_sidebars = { + "**": [ + "sidebars/localtoc.html", + "repository.html", + ] +} # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output diff --git a/docs/configuration.md b/docs/configuration.md index 43be971..bfb759d 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -13,6 +13,7 @@ caption: .env --- ``` + ## Checks configuration Argos uses a YAML configuration file to define the websites to monitor and the checks to run on these websites. diff --git a/docs/developer/models.md b/docs/developer/models.md new file mode 100644 index 0000000..8199130 --- /dev/null +++ b/docs/developer/models.md @@ -0,0 +1,33 @@ +# The data model + +```{mermaid} +classDiagram +direction RL +Task *-- Result : Have many +Task: id +Task: url +Task: domain +Task: check +Task: expected +Task: frequency +Task: selected_by +Task: selected_at +Task: completed_at +Task: next_run + +Result: id +Result: task_id +Result: task +Result: agent_id +Result: submitted_at +Result: status +Result: severity +Result: context +``` + + +```{literalinclude} ../../argos/server/models.py +--- +caption: models.py +--- +``` \ No newline at end of file diff --git a/docs/developer/new-check.md b/docs/developer/new-check.md new file mode 100644 index 0000000..586ec2c --- /dev/null +++ b/docs/developer/new-check.md @@ -0,0 +1,40 @@ +# Implementing a new check + +## Creating a new check class + +If you want to implement a new check, you need to create a new class that inherits from `argos.checks.BaseCheck`. + +You need to implement two methods, and specify the type of the data you want to check. + +Let's create a new check that ensures that the specified header is present. + +```python +class HeaderExists(BaseCheck): + """Checks that the response contains the specified header.""" + + config = "header-exists" + expected_cls = ExpectedStringValue + + async def run(self): + response = await self.http_client.head(self.task.url) + result = (self.expected.value in response.headers) + + return self.response(status=result) +``` + +## Using configuration values to determine the severity + +The agents don't have access to the configuration values, so they can't determine the severity of the check, albeit in some case that could be useful. + +If that's your case, you can implement the `finalize` method, and return some extra values in the `run` method, like this: + +```python + async def run(self): + # ... see earlier example + return self.response(status=result, extra_arg="extra_value") + + @classmethod + async def finalize(cls, config, result, extra_arg): + # You can use the extra_arg here to determine the severity + return Status.SUCCESS, Severity.OK +``` \ No newline at end of file diff --git a/docs/developer/overview.md b/docs/developer/overview.md new file mode 100644 index 0000000..252729b --- /dev/null +++ b/docs/developer/overview.md @@ -0,0 +1,29 @@ +# Technical overview + +Argos uses an agent and server architecture. The server is responsible for storing the configuration and the results of the checks. The agent is responsible for running the checks and sending the results to the server. + +## Sequence diagram + +```{mermaid} +sequenceDiagram + participant Agent + participant Server + loop + Agent->>Server: Hey, do you have some work for me? + Server-->>Agent: Here is some work + Agent->>Agent: Run checks + Agent->>Server: Here are the results + Server->>Server: Determine severity + Server->>Server: Store results + end +``` + +## Orchestration + +The server acts like a job queue. When an agent asks for work, the server will: +- mark the tasks as "selected by" the agent +- store the current date + +When it receives the results, it will: +- Remove the "selected by" and "selected at" fields +- Compute the next execution date. diff --git a/docs/index.md b/docs/index.md index 81d700a..5c76054 100644 --- a/docs/index.md +++ b/docs/index.md @@ -47,13 +47,21 @@ You want to know more about the internals ?. installation/getting-started installation/postgresql -configuration cli ``` ```{toctree} -:caption: Checks +:caption: Configuration :hidden: - +configuration checks +``` + +```{toctree} +:caption: Developer docs +:hidden: +developer/overview +developer/new-check +developer/models + ``` \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 6e18cc0..5c81813 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,7 @@ docs = [ "shibuya", "sphinx-design", "cogapp", + "sphinxcontrib-mermaid>=0.9,<1", ] [project.urls]