🔀 Merge branch 'fix-11' into 'main'

📝 — Improve documentation (fix #11)

Closes #11

See merge request framasoft/framaspace/argos!41
This commit is contained in:
Luc Didry 2024-04-10 15:24:35 +00:00
commit 013ee48cf5
27 changed files with 275 additions and 148 deletions

2
.gitignore vendored
View file

@ -5,3 +5,5 @@ venv
.env
public
*.swp
config.yaml
dist

View file

@ -29,7 +29,7 @@ pytest:
<<: *pull_cache
stage: test
script:
- make tests
- make test
djlint:
<<: *pull_cache

View file

@ -5,20 +5,21 @@ ORANGE=\033[0;33m
BLUE=\033[0;34m
NC=\033[0m # No Color
.PHONY: tests djlint pylint
.PHONY: test djlint pylint
venv: ## Create the venv
python3 -m venv venv
develop: venv ## Install the dev dependencies
venv/bin/pip install -e ".[dev,docs]"
docs: cog ## Build the docs
docs: cog public/mermaid.min.js ## Build the docs
venv/bin/sphinx-build docs public
curl -sL $$(grep mermaid.min.js public/search.html | cut -f 2 -d '"') --output public/mermaid.min.js
sed -e 's@https://unpkg.com/mermaid[^"]*"@mermaid.min.js"@' -i public/search.html public/genindex.html
sed -e 's@https://unpkg.com/mermaid[^"]*"@../mermaid.min.js"@' -i public/developer/models.html public/developer/overview.html
public/mermaid.min.js:
curl -sL $$(grep mermaid.min.js public/search.html | cut -f 2 -d '"') --output public/mermaid.min.js
cog: ## Run cog, to integrate the CLI options to the docs.
venv/bin/cog -r docs/*.md
tests: venv ## Run the tests
test: venv ## Run the tests
venv/bin/pytest
ruff: venv
venv/bin/ruff format --check .
@ -28,7 +29,7 @@ pylint: venv ## Runs pylint on the code
venv/bin/pylint argos
pylint-alembic: venv ## Runs pylint on alembic migration files
venv/bin/pylint --disable invalid-name,no-member alembic/versions/*.py
lint: djlint pylint
lint: djlint pylint pylint-alembic ruff
help:
@python3 -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)

View file

@ -16,20 +16,6 @@ Internally, a HTTP API is exposed, and a job queue is used to distribute the che
- **Python**: 3.11+
- **Backends**: SQLite (development), PostgreSQL 14+ (production)
## Todo:
- [ ] Do not return empty list on / when no results from agents. (!17)
- [X] donner un aperçu rapide de létat de la supervision.
- [X] Use background tasks for alerting (#23)
- [X] Delete outdated tasks from config (#19, !25)
- [X] Implement alerting tasks (#15, 16, !13)
- [X] Handles multiple alerting backends (email, sms, gotify) (!13)
- [X] add an "unknown" severity for check errors (!17)
- [X] Add a command to generate new authentication token (#22)
- [ ] Add a way to specify the severity of the alerts in the config
- [ ] Allow passing a dict to check
- [ ] A configuration flag can automatically add a check of 301 redirection from HTTP to HTTPS
## License
Copyright © 2023 Alexis Métaireau, Framasoft

View file

@ -0,0 +1 @@
VERSION = "0.1.0"

View file

@ -9,6 +9,7 @@ from alembic import command
from alembic.config import Config
from argos import logging
from argos import VERSION
from argos.agent import ArgosAgent
@ -40,6 +41,11 @@ def server():
pass
@cli.command()
def version():
click.echo(VERSION)
@cli.command()
@click.argument("server_url", envvar="ARGOS_AGENT_SERVER_URL")
@click.argument("auth", envvar="ARGOS_AGENT_TOKEN")
@ -111,8 +117,11 @@ def validate_max_results(ctx, param, value):
@click.option(
"--max-lock-seconds",
default=100,
help="The number of seconds after which a lock is considered stale, must be higher than 60 "
"(the checks have a timeout value of 60 seconds)",
help=(
"The number of seconds after which a lock is "
"considered stale, must be higher than 60 "
"(the checks have a timeout value of 60 seconds)"
),
callback=validate_max_lock_seconds,
)
@coroutine

View file

@ -1,4 +1,5 @@
"""Database models"""
from datetime import datetime, timedelta
from typing import List, Literal
@ -87,12 +88,12 @@ class Task(Base):
class Result(Base):
"""There is multiple results per tasks.
"""There are multiple results per task.
The results uses the informations returned by the agents.
The results store information returned by the agents.
The status is "Was the agent able to do the check?" while the severity
depends on the return value of the check.
You can read `status` as "Was the agent able to do the check?"
while the `severity` depends on the return value of the check.
"""
__tablename__ = "results"
@ -120,14 +121,16 @@ class Result(Base):
class ConfigCache(Base):
"""Contains some informations on the previous config state
"""Database model containing information on the current state
of the configuration.
Used to quickly determine if we need to update the tasks.
There is currently two cached settings:
This is used to determine if tasks are to be updated.
These settings are cached:
- general_frequency: the content of general.frequency setting, in minutes
ex: 5
- websites_hash: the sha256sum of websites setting, to allow a quick
comparison without looping through all websites
- websites_hash: the hash (sha256sum) of websites setting, to allow a quick
comparison without looping through all websites.
ex: 8b886e7db7b553fe99f6d5437f31745987e243c77b2109b84cf9a7f8bf7d75b1
"""

View file

@ -1,64 +0,0 @@
general:
frequency: "1m" # Run checks every minute.
# Which way do you want to be warned when a check goes to that severity?
alerts:
ok:
- local
warning:
- local
critical:
- local
unknown:
- local
# mail:
# mailfrom: no-reply@example.org
# host: 127.0.0.1
# port: 25
# ssl: False
# starttls: False
# auth:
# login: foo
# password: bar
# addresses:
# - foo@admin.example.org
# - bar@admin.example.org
# gotify:
# - url: https://example.org
# tokens:
# - foo
# - bar
service:
secrets:
- "1234"
# Secrets can be generated using `openssl rand -base64 32`.
ssl:
thresholds:
- "1d": critical
- "5d": warning
# It's also possible to define the checks in another file
# with the include syntax:
#
# websites: !include websites.yaml
#
websites:
- domain: "https://mypads.example.org"
paths:
- path: "/mypads/"
checks:
- status-is: 200
- body-contains: '<div id= "mypads"></div>'
- ssl-certificate-expiration: "on-check"
- path: "/admin/"
checks:
- status-is: 401
- domain: "https://munin.example.org"
paths:
- path: "/"
checks:
- status-is: 301
- path: "/munin/"
checks:
- status-is: 401

View file

@ -10,6 +10,8 @@ To access the API, you need to pass an authentication token in the `Authorizatio
"Authorization": "Bearer " + token
```
See the [CLI documentation](cli.md#server-generate-token-command) to generate tokens.
## Endpoints
You can also have access to the Swagger API documentation at `https://<argos-url>/docs`, and the ReDoc documentation at `https://<argos-url>/redoc`.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 KiB

View file

@ -28,6 +28,7 @@ Options:
Commands:
agent Get and run tasks to the provided server.
server
version
```
<!--[[[end]]]

View file

@ -5,11 +5,12 @@
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
import argos
project = "Argos"
copyright = "2023, Alexis Métaireau"
author = "Alexis Métaireau"
release = "0.0.1"
copyright = "2023, Alexis Métaireau, Framasoft"
author = "Alexis Métaireau, Framasoft"
release = argos.VERSION
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

View file

@ -7,7 +7,7 @@ There are actually two configuration files: one for the service and one for the
The server configuration is done using environment variables. You can put them in a `.env` file at the root of the project.
Here is a list of the useful variables, in the `.env` format:
```{literalinclude} ../.env.example
```{literalinclude} ../conf/.env.example
---
caption: .env
---
@ -34,21 +34,21 @@ ARGOS_DATABASE_URL = "postgresql://argos:argos@localhost/argos"
#### DB_POOL_SIZE
#### DB_MAX_OVERFLOW
These two help you configure the size of the pool, and the max overflow (until when do we accept a new connection ?) These are documented [in the SQLAlchemy docs in greater details](https://docs.sqlalchemy.org/en/20/core/pooling.html#sqlalchemy.pool.QueuePool.params.pool_size)
You configure the size of the database pool of connection, and the max overflow (until when new connections are accepted ?) These are documented [in the SQLAlchemy docs in greater details](https://docs.sqlalchemy.org/en/20/core/pooling.html#sqlalchemy.pool.QueuePool.params.pool_size)
```bash
DB_POOL_SIZE = 10
DB_MAX_OVERFLOW = 20
```
## Checks configuration
## Argos "checks" configuration
Argos uses a YAML configuration file to define the websites to monitor and the checks to run on these websites.
Here is a simple configuration file:
```{literalinclude} ../config-example.yaml
```{literalinclude} ../conf/config-example.yaml
---
caption: config.yaml
---

BIN
docs/dashboard.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View file

@ -1,4 +1,4 @@
# Main projects used by Argos
# Main dependencies used by Argos
## Python packages

View file

@ -0,0 +1,11 @@
# Installing for development
To install all what you need to develop on Argos, do:
```bash
git clone https://framagit.org/framasoft/framaspace/argos.git
cd argos
make develop
```
It will create a virtualenv and install all the needed dependencies in it.

82
docs/developer/release.md Normal file
View file

@ -0,0 +1,82 @@
# Releasing guide
Once in a while, we release this package. Here is how.
## Pre-requesites
You need to be in a working environment, with the dev dependencies installed. You can check it's the case by typing:
```bash
pip install -e ".[dev]"
```
You'll need to get an account on [PyPI](https://pypi.org), where the packages will be uploaded.
## The steps
Here is the quick version. If you need more details, some parts are explained in more details in the next sections.
```bash
# Ensure the tests run correctly
make test
# Bump the version, according to semantic versionning
hatch version minor # or `hatch version major`
# Create a tag on the git repository and push it
git tag "$(hatch version)" && git push
# Build the project
hatch build --clean
# Upload the project to PyPI
hatch publish
```
Aditionnaly, ensure it works well in a new environment.
## Bumping the version number
We follow semantic versionning conventions, and the version is specified in the `argos.__init__.py` file.
`hatch` provide commands to help with this:
```bash
hatch version minor
hatch version major
```
## Publishing
`hatch` will ask you for some credentials. Don't provide them the full credentials to you account, but instead you can [create a (scoped) token](https://pypi.org/manage/account/token/).
When asked for credentials, enter:
- `__token__` as the login
- the token as the value.
## Verifying it worked
Once published, you can test it works properly, by using pip, ideally in a new venv. Here's how:
```bash
python -m venv /tmp/argos
source /tmp/argos/bin/activate
pip install argos-monitoring
argos version # should output the proper version
```
## Using the test server
When running `hatch publish` the main PyPI instance will be used, which is not ideal for testing that it's doing what you want.
If you're still experimenting, you can use the [Test PyPI](https://test.pypi.org) server.
```bash
# Publishing on test PyPI
hatch build -r test
# Installing from test PyPI
pip install --index-url https://test.pypi.org/simple/ argos-monitoring
```

View file

@ -0,0 +1,17 @@
# Requirements
Depending on your setup, you might need different tools to develop on argos. We try to list them here.
## Mac OS
### Gnu Sed
You will need to have gnu-sed installed. "sed" installed by default on MacOS machines differ from the gnu version (It's used for some post-documentation-generation hooks)
```bash
brew install gnu-sed
# This will explain how to add it to your path (to replace the default one)
brew info gnu-sed
```

21
docs/developer/tests.md Normal file
View file

@ -0,0 +1,21 @@
# Tests and linting
## Tests
To launch the tests suite:
```bash
make test
```
## Linting
There is 4 lintings checks:
- `make djlint` will check the linting of the HTML templates
- `make pylint` will check the linting of Argos source code
- `make pylint-alembic` will check the linting of Alembics migrations files
- `make ruff` will check the linting of all files
You can launch all of them with:
```bash
make lint
```

BIN
docs/domains.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

View file

@ -10,33 +10,20 @@ Test how your websites respond to external checks, get notified when something g
- A **Website** allows to navigate the results of the checks.
- **HTTP API**: An HTTP API is exposed to get the results of the checks.
![Dashboard](dashboard.jpg)
![Argos web interface](capture.png)
## Installation
```{code-block} bash
pip install argos-monitoring
argos server start
argos agent http://localhost:8000 "<auth-token>"
```
```{literalinclude} ../config-example.yaml
---
caption: config.yaml
---
```
![Domains list](domains.jpg)
## Next
::::{grid} 2
:::{grid-item-card} Getting started
:::{grid-item-card} Installation
:link: installation/getting-started.html
The best way to get started with argos.
:::
:::{grid-item-card} Developper docs
:link: developer/overview.html
You want to know more about the internals ?.
You want to know more about the internals ?
:::
::::
@ -49,6 +36,7 @@ installation/getting-started
installation/postgresql
cli
api
changelog
```
```{toctree}
@ -68,11 +56,13 @@ checks
```{toctree}
:caption: Developer docs
:hidden:
developer/requirements
developer/installation
developer/overview
developer/dependencies
developer/new-check
developer/models
developer/migrations
developer/projects
changelog
developer/tests
```

View file

@ -15,21 +15,57 @@ source venv/bin/activate
pip install -e .
```
<!--
## Install with pip
```bash
pip install argos-monitoring
```
You may want to install Argos in a virtualenv:
```bash
python3 -m venv venv
source venv/bin/activate
pip install argos-monitoring
```
## Install from sources
Once you got the source locally, create a virtualenv and install the dependencies:
```bash
python3 -m venv venv
source venv/bin/activate
pip install -e .
```
-->
## Configure
### Configure the checks
The quickest way to get started is to copy the `config-example.yaml` file and edit it:
```bash
cp config-example.yaml config.yaml
cp conf/config-example.yaml config.yaml
```
<!--
The quickest way to get started is to get the `config-example.yaml` file from our repository and edit it:
```bash
wget https://framagit.org/framasoft/framaspace/argos/-/raw/main/conf/config-example.yaml -O config.yaml
```
-->
You can read more about the configuration in the [configuration section](../configuration.md).
## Starting the server
### Configure the server
Environment variables are used to configure the server. You can also put them in an `.env` file:
```{literalinclude} ../../.env.example
```{literalinclude} ../../conf/.env.example
---
caption: .env
---
@ -37,6 +73,8 @@ caption: .env
Please note that the only supported database engines are SQLite for development and PostgreSQL for production.
## Starting the server
Then you can start the server:
```bash
@ -45,12 +83,30 @@ argos server start
The server reads the `yaml` file at startup, and populates the tasks queue with the checks defined in the configuration.
## Generating a token
The agent needs an authentication token to be able to communicate with the server.
You can generate an authentication token with the following command:
```bash
argos server generate-token
```
Add the token in the configuration file, in the following setting:
```yaml
service:
secrets:
- "auth-token"
```
## Running the agent
You can run the agent on the same machine as the server, or on a different machine. The only requirement is that the agent can reach the server.
You can run the agent on the same machine as the server, or on a different machine.
The only requirement is that the agent can reach the server.
```bash
argos agent http://localhost:8000 "<auth-token>"
argos agent http://localhost:8000 "auth-token"
```
## Cleaning the database
@ -61,6 +117,6 @@ Here is a crontab example, which will clean the db each hour:
```bash
# Run the cleaning tasks every hour (at minute 7)
# Keeps 10 results per task, and locks the tasks for 1 hour
# Keeps 10 results per task, and remove tasks locks older than 1 hour
7 * * * * argos server cleandb --max-results 10 --max-lock-seconds 3600
```

View file

@ -1,10 +1,4 @@
# Use with PostgreSQL
If you intend to use argos with Postgresql, which is recommended for production, you can install it with the following commands:
```bash
pip install -e ".[postgres]"
```
# Install and configure PostgreSQL
Here are a few steps for you to install PostgreSQL on your system:

View file

@ -1,27 +1,33 @@
[build-system]
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "argos-monitoring"
version = "0.1.0"
dynamic = ["version"]
description = "Distributed supervision tool for HTTP."
authors = [
{ name = "Alexis Métaireau", email = "alexis@notmyidea.org" },
{ name = "Luc Didry", email = "luc+argos@framasoft.org" },
]
readme = "README.md"
classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
"License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
"Intended Audience :: System Administrators",
]
dependencies = [
"alembic>=1.13.0,<1.14",
"click>=8.1,<9",
"fastapi>=0.103,<0.104",
"gunicorn>=21.2,<22",
"httpx>=0.25,<1",
"Jinja2>=3.0,<4",
"psycopg2-binary>=2.9,<3",
"pydantic[email]>=2.4,<3",
"pydantic-settings>=2.0,<3",
"python-multipart>=0.0.9,<1",
@ -31,7 +37,6 @@ dependencies = [
"sqlalchemy-utils>=0.41,<1",
"tenacity>=8.2,<9",
"uvicorn>=0.23,<1",
"gunicorn>=21.2,<22",
]
[project.optional-dependencies]
@ -47,9 +52,7 @@ dev = [
"respx>=0.20,<1",
"ruff==0.1.5,<1",
"sphinx-autobuild",
]
postgres = [
"psycopg2-binary>=2.9,<3",
"hatch==1.9.4",
]
docs = [
"cogapp",
@ -61,14 +64,25 @@ docs = [
]
[project.urls]
homepage = "https://framagit.org/framasoft/framaspace/argos"
homepage = "https://framasoft.frama.io/framaspace/argos/"
repository = "https://framagit.org/framasoft/framaspace/argos"
"Funding" = "https://framasoft.org/en/#support"
"Tracker" = "https://framagit.org/framasoft/framaspace/argos/-/issues"
[tool.setuptools]
[tool.hatch.build.targets.sdist]
include = [
"/argos",
"/docs",
"/tests",
]
[tool.hatch.build.targets.wheel]
packages = ["argos"]
[tool.hatch.version]
path = "argos/__init__.py"
[project.scripts]
argos = "argos.commands:cli"