Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.py]
indent_style = space
indent_size = 4

[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_style = space
indent_size = 2

[*.{json}]
indent_style = space
indent_size = 2

[justfile]
indent_style = space
indent_size = 4

[Makefile]
indent_style = tab
56 changes: 9 additions & 47 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -67,55 +67,17 @@ ATLAS_AUTH_BEARER_TOKEN=
# ATLAS_NATS_ACK_WAIT=30s # (default)
# ATLAS_NATS_MAX_ACK_PENDING=1024 # (default)

# ============================================================
# ProjectArgus — Environment Configuration
# ============================================================
# Copy this file to .env and edit values for your deployment.
# cp .env.example .env
#
# .env is gitignored; .env.example is version-controlled.
# All variables have sensible defaults in docker-compose.yml,
# so only override what differs from the defaults below.
# ============================================================

# --- Service URLs (WSL2: 172.20.0.1 is the host gateway) ---

# Agamemnon agent-management API
# Copy this file to .env and fill in values before running the stack.
# .env is gitignored — never commit real credentials.

# Grafana admin password (default: changeme — change before exposing to a network)
GRAFANA_ADMIN_PASSWORD=changeme

# Agamemnon API base URL (WSL2 host gateway default)
AGAMEMNON_URL=http://172.20.0.1:8080

# Nestor research-pipeline API
# Nestor API base URL (WSL2 host gateway default)
NESTOR_URL=http://172.20.0.1:8081

# NATS monitoring endpoint
# NATS monitoring URL
NATS_URL=http://172.24.0.1:8222

# --- Grafana ---

# Host port Grafana is exposed on (container always listens on 3000)
GRAFANA_PORT=3001

# Grafana admin password — change this in production!
GF_SECURITY_ADMIN_PASSWORD=admin

# --- Prometheus ---

# Host port Prometheus is exposed on
PROMETHEUS_PORT=9090

# --- Loki ---

# Host port Loki is exposed on
LOKI_PORT=3100

# --- Exporter ---

# Host port the argus-exporter is exposed on
EXPORTER_PORT=9100

# --- Container names (optional — override to avoid collisions) ---

# PROMETHEUS_CONTAINER_NAME=argus-prometheus
# LOKI_CONTAINER_NAME=argus-loki
# PROMTAIL_CONTAINER_NAME=argus-promtail
# GRAFANA_CONTAINER_NAME=argus-grafana
# EXPORTER_CONTAINER_NAME=argus-exporter
84 changes: 54 additions & 30 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI

on:
push:
branches: ["main"]
branches: ["main", "feature/**", "fix/**", "chore/**"]
pull_request:
branches: ["main"]

Expand Down Expand Up @@ -137,39 +137,63 @@ jobs:
go test -race -coverprofile=coverage.out ./internal/...
go tool cover -func=coverage.out | tail -1

- name: go test (integration)
- name: Docker build (verify Dockerfile is buildable)
working-directory: dashboard
run: go test -race -tags=integration -timeout=60s ./tests/integration/...
run: docker build -t argus-dashboard:ci .

- name: Upload coverage profile
uses: actions/upload-artifact@v4
test:
name: Test exporter
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
name: coverage-profile
path: dashboard/coverage.out
if-no-files-found: warn

- name: golangci-lint
# v9 is required for golangci-lint v2 binaries; the older v6 action
# rejects "v2.x" version strings outright. SHA-pinned to v9.2.0
# (current latest as of 2026-05-07) per the repo's pin convention.
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
python-version: "3.11"

- name: Install test dependencies
run: pip install pytest

- name: Run tests
run: python -m pytest tests/ -v

lint:
name: Lint Python
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up Python
uses: actions/setup-python@v5
with:
version: v2.12.2
working-directory: dashboard
python-version: "3.11"

- name: govulncheck (SCA)
working-directory: dashboard
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
- name: Install ruff
run: pip install ruff

- name: Check templ generate (no-op)
working-directory: dashboard
run: |
go install github.com/a-h/templ/cmd/templ@latest
templ generate ./...
git diff --exit-code
- name: Run ruff
run: ruff check exporter/ tests/

- name: Docker build (verify Dockerfile is buildable)
working-directory: dashboard
run: docker build -t argus-dashboard:ci .
security:
name: Security scan
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install bandit
run: pip install bandit

- name: Run bandit
run: bandit -ll --skip B310,B202 -r exporter/
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ configs/nginx/htpasswd
htmlcov/
coverage.xml
.pytest_cache/
secrets/
__pycache__/
*.pyc
*.pyo
7 changes: 7 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,11 @@ description = "Allow credential-like strings in test fixtures and example files"
paths = [
'''tests/''',
'''\.env\.example$''',
'''htpasswd.example$''',
]

[[rules]]
description = "Detect htpasswd credential files"
id = "htpasswd"
regex = '''\$apr1\$|\$2y\$|\$2a\$'''
path = '''htpasswd'''
30 changes: 14 additions & 16 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-merge-conflict
- id: check-json
- repo: https://github.com/adrienverge/yamllint
rev: v1.35.1
hooks:
- id: yamllint
args: ["--config-file", ".yamllint.yaml"]
files: \.(yml|yaml)$
args: ["-d", "{extends: default, rules: {line-length: {max: 120}, truthy: disable}}"]

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.10
hooks:
- id: ruff
args: ["--fix"]

- repo: local
hooks:
- id: check-version-consistency
name: Check pixi.toml version matches CHANGELOG
language: python
entry: python scripts/check-version-consistency.py
pass_filenames: false
files: ^(pixi\.toml|CHANGELOG\.md)$
- id: bandit
name: bandit security scan
entry: bandit -ll --skip B310,B202 -r
language: system
files: ^exporter/.*\.py$
pass_filenames: true
20 changes: 10 additions & 10 deletions dashboards/nats-events.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "rate(gnatsd_varz_in_msgs[1m])",
"expr": "rate(nats_in_msgs_total[1m])",
"legendFormat": "msgs/s in",
"refId": "A"
}
Expand All @@ -37,7 +37,7 @@
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "rate(gnatsd_varz_out_msgs[1m])",
"expr": "rate(nats_out_msgs_total[1m])",
"legendFormat": "msgs/s out",
"refId": "A"
}
Expand All @@ -58,7 +58,7 @@
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "gnatsd_varz_jetstream_stats_storage",
"expr": "nats_jetstream_bytes",
"legendFormat": "Storage",
"refId": "A"
}
Expand All @@ -73,14 +73,14 @@
},
{
"id": 4,
"title": "Active Subscriptions",
"title": "Active Connections",
"type": "stat",
"gridPos": { "x": 18, "y": 0, "w": 6, "h": 4 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "gnatsd_varz_subscriptions",
"legendFormat": "Subscriptions",
"expr": "nats_connections",
"legendFormat": "Connections",
"refId": "A"
}
],
Expand All @@ -97,12 +97,12 @@
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "rate(gnatsd_varz_in_msgs[1m])",
"expr": "rate(nats_in_msgs_total[1m])",
"legendFormat": "In msg/s",
"refId": "A"
},
{
"expr": "rate(gnatsd_varz_out_msgs[1m])",
"expr": "rate(nats_out_msgs_total[1m])",
"legendFormat": "Out msg/s",
"refId": "B"
}
Expand All @@ -119,12 +119,12 @@
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "rate(gnatsd_varz_in_bytes[1m])",
"expr": "rate(nats_in_bytes_total[1m])",
"legendFormat": "Bytes in/s",
"refId": "A"
},
{
"expr": "rate(gnatsd_varz_out_bytes[1m])",
"expr": "rate(nats_out_bytes_total[1m])",
"legendFormat": "Bytes out/s",
"refId": "B"
}
Expand Down
16 changes: 12 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
networks:

Check warning on line 1 in docker-compose.yml

View workflow job for this annotation

GitHub Actions / Validate configs

1:1 [document-start] missing document start "---"
argus:
driver: bridge
loki-internal:
Expand All @@ -18,6 +18,8 @@
options:
max-size: "50m"
max-file: "3"
ports:
- "127.0.0.1:9090:9090"
expose:
- "9090"
volumes:
Expand All @@ -33,6 +35,12 @@
- "--web.console.libraries=/usr/share/prometheus/console_libraries"
- "--web.console.templates=/usr/share/prometheus/consoles"
- "--web.config.file=/etc/prometheus/prometheus.yml"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:9090/-/ready"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
networks:
- argus
deploy:
Expand Down Expand Up @@ -142,7 +150,7 @@
container_name: argus-alertmanager
restart: unless-stopped
ports:
- "9093:9093"
- "127.0.0.1:9093:9093"
volumes:
- ./configs/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
- alertmanager_data:/alertmanager
Expand All @@ -167,7 +175,7 @@
max-size: "50m"
max-file: "3"
ports:
- "${GRAFANA_PORT:-3001}:3000"
- "127.0.0.1:${GRAFANA_PORT:-3001}:3000"
volumes:
- ./dashboards:/var/lib/grafana/dashboards:ro
- ./configs/grafana:/etc/grafana/provisioning:ro
Expand Down Expand Up @@ -250,7 +258,7 @@
container_name: argus-dashboard
restart: unless-stopped
ports:
- "3002:3002"
- "127.0.0.1:3002:3002"
environment:
ATLAS_LISTEN_ADDR: ":3002"
ATLAS_AGAMEMNON_URL: ${AGAMEMNON_URL:-http://172.20.0.1:8080}
Expand Down Expand Up @@ -295,7 +303,7 @@
container_name: argus-jetstream-consumer
restart: unless-stopped
ports:
- "9101:9101"
- "127.0.0.1:9101:9101"
volumes:
- ./jetstream-consumer/consumer.py:/consumer.py:ro
command: sh -c "pip install nats-py -q && python /consumer.py"
Expand Down
Loading
Loading