CI / test (push) Has been cancelled
**ACLs (Access Control Lists):** - Ajout du type AclConfig dans sources/event.v (allowed_ips CIDR + allowed_tokens) - Chaque source webhook (Gitea, Uptime Kuma, Cron, Generic) supporte les ACLs - Validation IP via X-Forwarded-For / X-Real-IP avant HMAC - Validation Bearer token via Authorization header - Tests: 7 tests ACL (IP exact, CIDR, parse IPv4, ACL vide, IP+token combiné) **Plugin system:** - sources/plugin.v: runner exécutable externe, stdout JSON → Event - Exit 0 = publish, exit ≠ 0 = skip. Timeout configurable - Plugin loop dans server.v (goroutine, toutes les 60s) - Example: scripts/example-plugin-disk.sh (vérifie espace disque) **Docs:** - README.md: ajout source Plugin + section Features complète - ARCHITECTURE.md: flux Plugin, flux ACL, endpoints /metrics /api/silence - ROADMAP.md: Phase 5 → 8/8 complet, ajout v0.6.0 - ntfy-bridge.example.yaml: sections ACLs et Plugins commentées - Version bump: 0.5.0 → 0.6.0
145 lines
4.2 KiB
V
145 lines
4.2 KiB
V
module sources
|
|
|
|
pub struct Event {
|
|
pub mut:
|
|
source string
|
|
name string
|
|
topic string
|
|
priority int
|
|
tags []string
|
|
message string
|
|
raw string
|
|
click_url string // v0.5: URL opened when notification is clicked
|
|
actions []Action // v0.5: Ntfy action buttons
|
|
}
|
|
|
|
pub fn (e Event) clone() Event {
|
|
return Event{
|
|
source: e.source
|
|
name: e.name
|
|
topic: e.topic
|
|
priority: e.priority
|
|
tags: e.tags.clone()
|
|
message: e.message
|
|
raw: e.raw
|
|
click_url: e.click_url
|
|
actions: e.actions.clone()
|
|
}
|
|
}
|
|
|
|
pub struct Action {
|
|
pub:
|
|
action string // view, broadcast, http
|
|
label string
|
|
url string
|
|
clear bool // whether to dismiss notification after action
|
|
}
|
|
|
|
// v0.6 — ACL per webhook path
|
|
pub struct AclConfig {
|
|
pub mut:
|
|
allowed_ips []string @[json: 'allowed_ips'] // CIDR ranges or single IPs
|
|
allowed_tokens []string @[json: 'allowed_tokens'] // bearer tokens
|
|
}
|
|
|
|
pub struct GiteaSource {
|
|
pub mut:
|
|
name string @[json: 'name']
|
|
webhook_path string @[json: 'webhook_path']
|
|
topic string @[json: 'topic']
|
|
template string @[json: 'template']
|
|
priority_map map[string]int @[json: 'priority_map']
|
|
tags []string @[json: 'tags']
|
|
repo string @[json: 'repo']
|
|
acl AclConfig @[json: 'acl']
|
|
}
|
|
|
|
pub struct UptimeKumaState {
|
|
pub mut:
|
|
priority int @[json: 'priority']
|
|
tags []string @[json: 'tags']
|
|
}
|
|
|
|
pub struct UptimeKumaSource {
|
|
pub mut:
|
|
name string @[json: 'name']
|
|
webhook_path string @[json: 'webhook_path']
|
|
topic string @[json: 'topic']
|
|
template string @[json: 'template']
|
|
priority_map map[string]int @[json: 'priority_map']
|
|
tags []string @[json: 'tags']
|
|
state_map map[string]UptimeKumaState @[json: 'state_map']
|
|
acl AclConfig @[json: 'acl']
|
|
}
|
|
|
|
pub struct DockerSource {
|
|
pub mut:
|
|
name string @[json: 'name']
|
|
topic string @[json: 'topic']
|
|
template string @[json: 'template']
|
|
priority_map map[string]int @[json: 'priority_map']
|
|
tags []string @[json: 'tags']
|
|
hosts []string @[json: 'hosts']
|
|
events []string @[json: 'events']
|
|
}
|
|
|
|
pub struct HttpCheck {
|
|
pub mut:
|
|
url string @[json: 'url']
|
|
topic string @[json: 'topic']
|
|
priority int @[json: 'priority']
|
|
expect_status int @[json: 'expect_status']
|
|
timeout int @[json: 'timeout']
|
|
template string @[json: 'template']
|
|
}
|
|
|
|
pub struct HttpPollSource {
|
|
pub mut:
|
|
name string @[json: 'name']
|
|
interval int @[json: 'interval']
|
|
checks []HttpCheck @[json: 'checks']
|
|
}
|
|
|
|
pub struct CronSource {
|
|
pub mut:
|
|
name string @[json: 'name']
|
|
webhook_path string @[json: 'webhook_path']
|
|
topic string @[json: 'topic']
|
|
template string @[json: 'template']
|
|
priority_map map[string]int @[json: 'priority_map']
|
|
tags []string @[json: 'tags']
|
|
acl AclConfig @[json: 'acl']
|
|
}
|
|
|
|
pub struct GenericSource {
|
|
pub mut:
|
|
name string @[json: 'name']
|
|
webhook_path string @[json: 'webhook_path']
|
|
topic string @[json: 'topic']
|
|
template string @[json: 'template']
|
|
priority_map map[string]int @[json: 'priority_map']
|
|
tags []string @[json: 'tags']
|
|
acl AclConfig @[json: 'acl']
|
|
}
|
|
|
|
// v0.6 — Plugin source: external executable that receives JSON on stdin, outputs JSON on stdout
|
|
pub struct PluginSource {
|
|
pub mut:
|
|
name string @[json: 'name']
|
|
topic string @[json: 'topic']
|
|
command string @[json: 'command'] // path to executable
|
|
timeout int @[json: 'timeout'] // seconds (default: 10)
|
|
acl AclConfig @[json: 'acl']
|
|
}
|
|
|
|
// render_source_template applies variable substitution to a template string.
|
|
// Placeholders are {varname}. Shared by all source transformers in this module.
|
|
pub fn render_source_template(template string, vars map[string]string) string {
|
|
mut result := template.clone()
|
|
for key, value in vars {
|
|
placeholder := '{${key}}'
|
|
result = result.replace(placeholder, value)
|
|
}
|
|
return result
|
|
}
|