2025-11-15 23:00:03 +01:00
|
|
|
package config
|
|
|
|
|
|
|
|
|
|
import (
|
2025-11-17 20:31:09 +01:00
|
|
|
_ "embed"
|
2025-11-15 23:00:03 +01:00
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
"path"
|
|
|
|
|
"wazuh-notify/log"
|
|
|
|
|
|
|
|
|
|
"github.com/BurntSushi/toml"
|
|
|
|
|
)
|
|
|
|
|
|
2025-11-17 20:31:09 +01:00
|
|
|
//go:embed default-config.toml
|
|
|
|
|
var DefaultConfigFile []byte
|
2025-11-15 23:00:03 +01:00
|
|
|
var File Config
|
|
|
|
|
|
2025-11-17 21:27:53 +01:00
|
|
|
// WARNING: this code is ai generated
|
2025-11-15 23:00:03 +01:00
|
|
|
func Read() error {
|
|
|
|
|
const SystemConfigPath = "/etc/wazuh-notify/wazuh-notify-config.toml"
|
|
|
|
|
execPath, _ := os.Executable()
|
2025-11-17 20:31:09 +01:00
|
|
|
LocalConfigPath := path.Join(path.Dir(execPath), "wazuh-notify-config.toml")
|
2025-11-15 23:00:03 +01:00
|
|
|
|
2025-11-17 21:27:53 +01:00
|
|
|
err := toml.Unmarshal(DefaultConfigFile, &File)
|
2025-11-17 20:31:09 +01:00
|
|
|
if err != nil {
|
2025-11-17 21:27:53 +01:00
|
|
|
log.Log(fmt.Sprintf("CRITICAL: Failed to parse embedded default config: %v", err))
|
|
|
|
|
return err
|
2025-11-15 23:00:03 +01:00
|
|
|
}
|
|
|
|
|
|
2025-11-17 21:27:53 +01:00
|
|
|
var userTomlFile []byte
|
|
|
|
|
var readErr error
|
|
|
|
|
var configPath string
|
|
|
|
|
|
|
|
|
|
userTomlFile, readErr = os.ReadFile(SystemConfigPath)
|
|
|
|
|
if readErr == nil {
|
|
|
|
|
configPath = SystemConfigPath
|
|
|
|
|
} else {
|
|
|
|
|
userTomlFile, readErr = os.ReadFile(LocalConfigPath)
|
|
|
|
|
if readErr == nil {
|
|
|
|
|
configPath = LocalConfigPath
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-17 20:31:09 +01:00
|
|
|
|
2025-11-17 21:27:53 +01:00
|
|
|
if readErr != nil {
|
|
|
|
|
log.Log("No user config file found. Attempting to create default on disk.")
|
2025-11-17 20:31:09 +01:00
|
|
|
|
2025-11-17 21:27:53 +01:00
|
|
|
errMkdir := os.MkdirAll(path.Dir(SystemConfigPath), os.ModePerm)
|
2025-11-17 20:31:09 +01:00
|
|
|
errWrite := os.WriteFile(SystemConfigPath, DefaultConfigFile, 0600)
|
|
|
|
|
|
|
|
|
|
if errMkdir != nil || errWrite != nil {
|
2025-11-17 21:27:53 +01:00
|
|
|
log.Log(fmt.Sprintf("Warning: Could not write default config to %s (%v).", SystemConfigPath, errWrite))
|
|
|
|
|
log.Log("Using embedded default configuration only.")
|
2025-11-17 20:31:09 +01:00
|
|
|
} else {
|
2025-11-17 21:27:53 +01:00
|
|
|
log.Log(fmt.Sprintf("Successfully created default config at %s.", SystemConfigPath))
|
2025-11-17 20:31:09 +01:00
|
|
|
}
|
|
|
|
|
|
2025-11-17 21:27:53 +01:00
|
|
|
log.Log("TOML configuration loaded successfully from Embedded Default")
|
|
|
|
|
return nil
|
2025-11-15 23:00:03 +01:00
|
|
|
}
|
|
|
|
|
|
2025-11-17 21:27:53 +01:00
|
|
|
overrideErr := toml.Unmarshal(userTomlFile, &File)
|
|
|
|
|
if overrideErr != nil {
|
|
|
|
|
log.Log(fmt.Sprintf("Error parsing user configuration from %s: %v", configPath, overrideErr))
|
|
|
|
|
return overrideErr
|
2025-11-15 23:00:03 +01:00
|
|
|
}
|
2025-11-17 20:31:09 +01:00
|
|
|
|
2025-11-17 21:27:53 +01:00
|
|
|
log.Log(fmt.Sprintf("TOML configuration loaded successfully. Defaults merged with %s", configPath))
|
2025-11-15 23:00:03 +01:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Config holds the entire configuration structure defined in the TOML file.
|
|
|
|
|
type Config struct {
|
|
|
|
|
General General `toml:"general"`
|
|
|
|
|
PriorityMaps []PriorityMap `toml:"priority_map"`
|
|
|
|
|
Discord Discord `toml:"discord"`
|
|
|
|
|
Ntfy Ntfy `toml:"ntfy"`
|
|
|
|
|
Slack Slack `toml:"slack"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// General maps the values within the [general] TOML table.
|
|
|
|
|
type General struct {
|
|
|
|
|
Targets string `toml:"targets"`
|
|
|
|
|
FullAlert string `toml:"full_alert"`
|
|
|
|
|
ExcludedRules string `toml:"excluded_rules"`
|
|
|
|
|
ExcludedAgents string `toml:"excluded_agents"`
|
|
|
|
|
ExcludeDescriptions []string `toml:"exclude_descriptions"`
|
|
|
|
|
Sender string `toml:"sender"`
|
|
|
|
|
Click string `toml:"click"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PriorityMap maps the values within a single [[priority_map]] TOML table entry.
|
|
|
|
|
type PriorityMap struct {
|
|
|
|
|
ThreatMap []int `toml:"threat_map"`
|
|
|
|
|
MentionThreshold int `toml:"mention_threshold"`
|
|
|
|
|
NotifyThreshold int `toml:"notify_threshold"`
|
|
|
|
|
Color int `toml:"color"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Discord struct {
|
|
|
|
|
Webhook string `toml:"webhook"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ntfy maps the values within the [ntfy] TOML table.
|
|
|
|
|
type Ntfy struct {
|
|
|
|
|
Webhook string `toml:"webhook"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Slack maps the values within the [slack] TOML table.
|
|
|
|
|
type Slack struct {
|
|
|
|
|
Webhook string `toml:"webhook"`
|
|
|
|
|
}
|