From 1e4320c2a1ef97bd3d776bfcdc0ec6d7ed32ab68 Mon Sep 17 00:00:00 2001 From: Mateusz Skoczek Date: Mon, 9 Feb 2026 18:47:19 +0100 Subject: [PATCH] refactoring --- {.github => .gitea}/config/gitversion.yml | 8 +- .gitea/readme/icon.png | Bin 0 -> 13966 bytes .gitea/workflows/analyze.yml | 34 +++++++ .gitea/workflows/analyze_and_publish.yml | 75 ++++++++++++++++ .github/workflows/pull_request_dev.yml | 26 ------ .github/workflows/pull_request_master.yml | 26 ------ .github/workflows/push_dev.yml | 26 ------ .github/workflows/push_master.yml | 101 --------------------- README.md | 105 +++++++++++++++++++++- RELEASE.md | 3 - requirements.txt | 2 + ipsec_exporter.py => src/__main__.py | 2 +- src/app.py | 6 +- src/metrics_source.py | 2 +- src/prometheus_metrics_server.py | 2 +- 15 files changed, 223 insertions(+), 195 deletions(-) rename {.github => .gitea}/config/gitversion.yml (59%) create mode 100644 .gitea/readme/icon.png create mode 100644 .gitea/workflows/analyze.yml create mode 100644 .gitea/workflows/analyze_and_publish.yml delete mode 100644 .github/workflows/pull_request_dev.yml delete mode 100644 .github/workflows/pull_request_master.yml delete mode 100644 .github/workflows/push_dev.yml delete mode 100644 .github/workflows/push_master.yml delete mode 100644 RELEASE.md create mode 100644 requirements.txt rename ipsec_exporter.py => src/__main__.py (71%) diff --git a/.github/config/gitversion.yml b/.gitea/config/gitversion.yml similarity index 59% rename from .github/config/gitversion.yml rename to .gitea/config/gitversion.yml index 94fdb98..aa3a017 100644 --- a/.github/config/gitversion.yml +++ b/.gitea/config/gitversion.yml @@ -1,11 +1,9 @@ next-version: 1.0.0 +mode: ContinuousDeployment assembly-versioning-scheme: MajorMinorPatch assembly-file-versioning-scheme: MajorMinorPatch branches: - master: - regex: ^master$ - mode: ContinuousDelivery + main: + regex: ^main$ increment: Patch - tag: '' - is-release-branch: true diff --git a/.gitea/readme/icon.png b/.gitea/readme/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..71df6daa287f8883bcf46df4ce48781bedc6029f GIT binary patch literal 13966 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 literal 0 HcmV?d00001 diff --git a/.gitea/workflows/analyze.yml b/.gitea/workflows/analyze.yml new file mode 100644 index 0000000..4927bf1 --- /dev/null +++ b/.gitea/workflows/analyze.yml @@ -0,0 +1,34 @@ +name: Analyze code + +on: + push: + branches: + - "dev" + paths: + - "src**" + - "requirements.txt" + pull_request: + branches: + - "dev" + - "main" + paths: + - "src**" + - "requirements.txt" + +jobs: + analyze: + name: Analyze code + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.10" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install pylint + - name: Analysing the code with pylint + run: pylint --exit-zero $(git ls-files 'src/*.py') diff --git a/.gitea/workflows/analyze_and_publish.yml b/.gitea/workflows/analyze_and_publish.yml new file mode 100644 index 0000000..2b94cad --- /dev/null +++ b/.gitea/workflows/analyze_and_publish.yml @@ -0,0 +1,75 @@ +name: Analyze code and publish script + +on: + push: + branches: + - "main" + paths: + - "src**" + - "requirements.txt" + +jobs: + analyze: + name: Analyze code + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.10" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install pylint + - name: Analysing the code with pylint + run: pylint --exit-zero $(git ls-files 'src/*.py') + publish: + name: Publish script + needs: analyze + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + with: + fetch-depth: 0 + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 10.0.x + - name: Setup GitVersion + uses: gittools/actions/gitversion/setup@v4.2.0 + with: + versionSpec: 6.4.x + - name: Determine version + uses: gittools/actions/gitversion/execute@v4.2.0 + id: gitversion + with: + configFilePath: ./.gitea/config/gitversion.yml + - name: Create package root directory + run: | + mkdir package + mkdir package/ipsec_exporter + cp -r src/* package/ipsec_exporter/ + cp requirements.txt package/requirements.txt + - name: Create .TAR.GZ archive + uses: ksm2/archive-action@v1 + with: + format: "tar.gz" + name: ipsec_exporter_${{steps.gitversion.outputs.SemVer}} + root-directory: "package" + - name: Create .ZIP archive + uses: ksm2/archive-action@v1 + with: + format: "zip" + name: ipsec_exporter_${{steps.gitversion.outputs.SemVer}} + root-directory: "package" + - name: Create Release + uses: akkuman/gitea-release-action@v1 + with: + tag_name: ${{steps.gitversion.outputs.SemVer}} + name: ${{steps.gitversion.outputs.SemVer}} + files: |- + ipsec_exporter_${{steps.gitversion.outputs.SemVer}}.tar.gz + ipsec_exporter_${{steps.gitversion.outputs.SemVer}}.zip + \ No newline at end of file diff --git a/.github/workflows/pull_request_dev.yml b/.github/workflows/pull_request_dev.yml deleted file mode 100644 index de96278..0000000 --- a/.github/workflows/pull_request_dev.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Chack code on dev pull request - -on: - pull_request: - branches: - - "dev" - paths: - - "ipsec_exporter.py" - - "src/*" - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install pylint - - name: Analysing the code with pylint - run: pylint --exit-zero $(git ls-files '*.py') diff --git a/.github/workflows/pull_request_master.yml b/.github/workflows/pull_request_master.yml deleted file mode 100644 index f6fdf8e..0000000 --- a/.github/workflows/pull_request_master.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Chack code on master pull request - -on: - pull_request: - branches: - - "master" - paths: - - "ipsec_exporter.py" - - "src/*" - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install pylint - - name: Analysing the code with pylint - run: pylint --exit-zero $(git ls-files '*.py') diff --git a/.github/workflows/push_dev.yml b/.github/workflows/push_dev.yml deleted file mode 100644 index 1b6d949..0000000 --- a/.github/workflows/push_dev.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Chack code on dev push - -on: - push: - branches: - - "dev" - paths: - - "ipsec_exporter.py" - - "src/*" - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install pylint - - name: Analysing the code with pylint - run: pylint --exit-zero $(git ls-files '*.py') diff --git a/.github/workflows/push_master.yml b/.github/workflows/push_master.yml deleted file mode 100644 index c59cf13..0000000 --- a/.github/workflows/push_master.yml +++ /dev/null @@ -1,101 +0,0 @@ -name: Check code and publish on master push - -on: - push: - branches: - - "master" - paths: - - "src/*.py" - - "*.py" - -jobs: - check: - name: Code check - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Setup Python - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - name: Setup GitVersion - uses: gittools/actions/gitversion/setup@v0.9.7 - with: - versionSpec: 5.x - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install prometheus_client - pip install pylint - - name: Analysing the code with pylint - run: pylint --exit-zero $(git ls-files '*.py') - - name: Determine Version - uses: gittools/actions/gitversion/execute@v0.9.7 - id: gitversion - with: - useConfigFile: true - configFilePath: ./.github/config/gitversion.yml - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: src - path: | - ./ - !./.github/ - !./.gitignore - !./.git/ - outputs: - version: ${{ steps.gitversion.outputs.SemVer }} - publish: - name: Publish - needs: check - runs-on: ubuntu-latest - steps: - - name: Download artifact - uses: actions/download-artifact@v3 - with: - name: src - path: ./data/ - - name: Create zip - uses: ihiroky/archive-action@v1 - with: - root_dir: ./data/ - file_path: ipsec_exporter_${{ needs.check.outputs.version }}.zip - - name: Create tar.gz - uses: ihiroky/archive-action@v1 - with: - root_dir: ./data/ - file_path: ipsec_exporter_${{ needs.check.outputs.version }}.tar.gz - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ needs.check.outputs.version }} - release_name: ${{ needs.check.outputs.version }} - body_path: ./data/RELEASE.md - draft: false - prerelease: false - - name: Upload zip archive - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./ipsec_exporter_${{ needs.check.outputs.version }}.zip - asset_name: ipsec_exporter_${{ needs.check.outputs.version }}.zip - asset_content_type: application/zip - - name: Upload tar.gz archive - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./ipsec_exporter_${{ needs.check.outputs.version }}.tar.gz - asset_name: ipsec_exporter_${{ needs.check.outputs.version }}.tar.gz - asset_content_type: application/gzip - diff --git a/README.md b/README.md index db69113..75d4c29 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,103 @@ -# IPsecExporter -Prometheus IPsec metrics exporter for Libreswan +

+ +

IPsec Exporter

+ +

Metrics exporter for Libreswan IPsec VPN for use with Prometheus and Grafana

+ +

Metrics exporter written in Python for IPsec VPN server set up with this scripts (probably works with any Libreswan IPsec server).

+ +--- + +## Support status + +> [!Warning] +> App is no longer maintained. Last time, it was updated on April 2024. There is no guarantee that it works with newer versions of Libreswan. I leave the repository mainly as a sample of my work. + +## Features + +- Read metrics from Libreswan status commands and export them to the Prometheus server +- Set read interval +- Define custom metrics and metrics sources + +## Installation + +Download latest package version from Releases tab, unpack, install requirements and you good to go + +**Requirements** + +- Prometheus server set up +- Python installed +- PIP packages: + - `argparse` + - `prometheus_client` + +You can also use `requirements.txt` file to install PIP dependencies + +``` +pip install -r requirements.txt +``` + +## Usage + +``` +python ipsec_exporter [additional_options] +``` + +**Additional options:** + +- `--address
`, `-a
` - Prometheus server address (default: `0.0.0.0`) +- `--port `, `-p ` - Prometheus server port (default: `9446`) +- `--interval `, `-i ` - metrics read interval (in seconds, default: `1`) + +**Run as service:** + +You can just run command and leave terminal on, but you probably want to run exporter as a service. + +1. Create new service file in `/etc/systemd/system/` and use text editor of your choice to edit it (as root user or with `sudo`): `vim /etc/systemd/system/ipsec_exporter.service` +2. Paste the text below and adapt it to your setup + +``` +[Unit] +Description=Metrics exporter for Libreswan IPsec VPN for use with Prometheus +After=multi-user.target + +[Service] +ExecStart=python /path/to/app/directory/ipsec_exporter -a 0.0.0.0 -p 9446 -i 10 +Type=simple + +[Install] +WantedBy=multi-user.target +``` + +3. Save the file +4. Reload services (as root user or with `sudo`): `systemctl daemon-reload` +5. Enable service (as root user or with `sudo`): `systemctl enable ipsec_exporter` +6. Start service (as root user or with `sudo`): `systemctl start ipsec_exporter` + +## Custom metrics + +You can define your own metrics and metrics sources in `main` method of `App` class in `ipsec_exporter/app.py` file. + +**Regular command-based metrics source:** + +1. Define metrics source: `source = CommandMetricsSource("command")` +2. Define metrics with regular expression (regular expression have to contain wildcard "VALUE"): `source.add_metric("metric_name", r"current\.states\.(?P\w+)=(?P\d+)")` +3. Add metric source: `server.add_metrics_source(source)` + +Exporter will extract all metrics from command output, basing on regular expressions. + +**Fully custom metrics source:** + +1. Create new metric class that inherits from a `CustomMetric` class +2. You can define what you want in it, but it must meet several requirements (there is example in `ipsec_exporter/metric.py` - `IPsecTrafficCustomMetric`): + - It has to have constructor (`__init__(self, name: str, description: str = "")`), inside of which you will define labels and call superconstructor (`super().__init__(name, labels, description)`) + - It has to have update method (`update(self)` - this method will be called cyclically based on the interval), inside of which at the start you will clear `gauge` attribute (`self.gauge.clear()`) and set labels values (`self.gauge.labels(l1, l2).set(value)`) +3. Define metrics source: `source = CustomMetricsSource()` +4. Add metric to the source: `source.add_metric(ExampleCustomMetric("metric_name"))` +5. Add metric source: `server.add_metrics_source(source)` + +## Attribution + +You can copy this repository and create your own version of the app freely. However, it would be nice if you included URL to this repository in the description to your repository or in README file. + +- Icon by Icons8 \ No newline at end of file diff --git a/RELEASE.md b/RELEASE.md deleted file mode 100644 index 6f02c3c..0000000 --- a/RELEASE.md +++ /dev/null @@ -1,3 +0,0 @@ -# Changelog - -- Error fix diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0f0b7ac --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +argparse +prometheus_client \ No newline at end of file diff --git a/ipsec_exporter.py b/src/__main__.py similarity index 71% rename from ipsec_exporter.py rename to src/__main__.py index 4b586ac..f573483 100644 --- a/ipsec_exporter.py +++ b/src/__main__.py @@ -1,4 +1,4 @@ -from src.app import App +from app import App if __name__ == "__main__": app = App() diff --git a/src/app.py b/src/app.py index f79a690..d406d5c 100644 --- a/src/app.py +++ b/src/app.py @@ -1,7 +1,7 @@ from argparse import * -from src.prometheus_metrics_server import * -from src.metrics_source import * -from src.metric import * +from prometheus_metrics_server import * +from metrics_source import * +from metric import * class App: args: Namespace diff --git a/src/metrics_source.py b/src/metrics_source.py index adc319f..87c9eac 100644 --- a/src/metrics_source.py +++ b/src/metrics_source.py @@ -1,5 +1,5 @@ from abc import ABC, abstractmethod -from src.metric import Metric, CommandMetric, CustomMetric +from metric import Metric, CommandMetric, CustomMetric import os diff --git a/src/prometheus_metrics_server.py b/src/prometheus_metrics_server.py index b96affa..097e36b 100644 --- a/src/prometheus_metrics_server.py +++ b/src/prometheus_metrics_server.py @@ -1,6 +1,6 @@ import time import prometheus_client -from src.metrics_source import MetricsSource +from metrics_source import MetricsSource