133 lines
4.7 KiB
Go
133 lines
4.7 KiB
Go
package config
|
||
|
||
import (
|
||
"fmt"
|
||
"net"
|
||
"net/url"
|
||
"strconv"
|
||
"strings"
|
||
|
||
"git.apinb.com/bsm-sdk/core/conf"
|
||
)
|
||
|
||
var Spec SrvConfig
|
||
|
||
type AlertForwardConf struct {
|
||
BaseURL string `yaml:"base_url"`
|
||
InternalKey string `yaml:"internal_key"`
|
||
Enabled bool `yaml:"enabled"`
|
||
DefaultPolicyID uint `yaml:"default_policy_id"`
|
||
}
|
||
|
||
type IngestConf struct {
|
||
SyslogListenAddr string `yaml:"syslog_listen_addr"`
|
||
TrapListenAddr string `yaml:"trap_listen_addr"`
|
||
RuleRefreshSecs int `yaml:"rule_refresh_secs"`
|
||
}
|
||
|
||
type ResourceEventConf struct {
|
||
// HMACSecret 用于校验 dc-control 推送签名(X-Event-Signature)。
|
||
HMACSecret string `yaml:"hmac_secret"`
|
||
// MaxSkewSecs 允许事件时间与服务端时间的最大偏差(秒)。
|
||
MaxSkewSecs int `yaml:"max_skew_secs"`
|
||
}
|
||
|
||
type OTLPConf struct {
|
||
InternalKey string `yaml:"internal_key"`
|
||
}
|
||
|
||
type SystemSettingsConf struct {
|
||
BaseURL string `yaml:"base_url"`
|
||
RefreshSeconds int `yaml:"refresh_seconds"`
|
||
TimeoutSeconds int `yaml:"timeout_seconds"`
|
||
}
|
||
|
||
type SrvConfig struct {
|
||
conf.Base `yaml:",inline"`
|
||
Databases *conf.DBConf `yaml:"Databases"`
|
||
MicroService *conf.MicroServiceConf `yaml:"MicroService"`
|
||
Rpc map[string]conf.RpcConf `yaml:"Rpc"`
|
||
Gateway *conf.GatewayConf `yaml:"Gateway"`
|
||
Apm *conf.ApmConf `yaml:"APM"`
|
||
AlertForward *AlertForwardConf `yaml:"AlertForward"`
|
||
Ingest IngestConf `yaml:"Ingest"`
|
||
ResourceEvent ResourceEventConf `yaml:"ResourceEvent"`
|
||
OTLP OTLPConf `yaml:"OTLP"`
|
||
SystemSettings SystemSettingsConf `yaml:"SystemSettings"`
|
||
}
|
||
|
||
func New(srvKey string) {
|
||
conf.New(srvKey, &Spec)
|
||
if err := Validate(); err != nil {
|
||
panic(fmt.Errorf("logs 配置校验失败: %w", err))
|
||
}
|
||
Spec.Addr = net.JoinHostPort(Spec.BindIP, Spec.Port)
|
||
conf.PrintInfo(Spec.Addr)
|
||
}
|
||
|
||
// Validate 校验日志服务配置,不生成随机端口、监听地址或刷新间隔。
|
||
func Validate() error {
|
||
Spec.Service = strings.TrimSpace(Spec.Service)
|
||
Spec.Port = strings.TrimSpace(Spec.Port)
|
||
Spec.BindIP = strings.TrimSpace(Spec.BindIP)
|
||
Spec.ResourceEvent.HMACSecret = strings.TrimSpace(Spec.ResourceEvent.HMACSecret)
|
||
Spec.OTLP.InternalKey = strings.TrimSpace(Spec.OTLP.InternalKey)
|
||
Spec.SystemSettings.BaseURL = strings.TrimRight(strings.TrimSpace(Spec.SystemSettings.BaseURL), "/")
|
||
if Spec.Service == "" {
|
||
return fmt.Errorf("Service 不能为空")
|
||
}
|
||
port, err := strconv.Atoi(Spec.Port)
|
||
if err != nil || port < 1 || port > 65535 {
|
||
return fmt.Errorf("Port 必须是 1 到 65535 的整数")
|
||
}
|
||
if net.ParseIP(Spec.BindIP) == nil {
|
||
return fmt.Errorf("BindIP 必须是明确的 IPv4 或 IPv6 地址")
|
||
}
|
||
if Spec.Databases == nil || strings.TrimSpace(Spec.Databases.Driver) == "" || len(Spec.Databases.Source) == 0 {
|
||
return fmt.Errorf("Databases.Driver 和 Databases.Source 不能为空")
|
||
}
|
||
if strings.TrimSpace(Spec.Cache) == "" {
|
||
return fmt.Errorf("Cache 不能为空")
|
||
}
|
||
if Spec.ResourceEvent.HMACSecret == "" || Spec.ResourceEvent.MaxSkewSecs <= 0 {
|
||
return fmt.Errorf("ResourceEvent.hmac_secret 和 max_skew_secs 必须有效")
|
||
}
|
||
if Spec.OTLP.InternalKey == "" {
|
||
return fmt.Errorf("OTLP.internal_key 不能为空")
|
||
}
|
||
parsedSystemSettingsURL, err := url.Parse(Spec.SystemSettings.BaseURL)
|
||
if err != nil || parsedSystemSettingsURL.Host == "" || (parsedSystemSettingsURL.Scheme != "http" && parsedSystemSettingsURL.Scheme != "https") {
|
||
return fmt.Errorf("SystemSettings.base_url 必须是完整的 HTTP 或 HTTPS 地址")
|
||
}
|
||
if Spec.SystemSettings.RefreshSeconds <= 0 || Spec.SystemSettings.TimeoutSeconds <= 0 {
|
||
return fmt.Errorf("SystemSettings.refresh_seconds 和 timeout_seconds 必须大于 0")
|
||
}
|
||
if Spec.Ingest.RuleRefreshSecs <= 0 {
|
||
return fmt.Errorf("Ingest.rule_refresh_secs 必须大于 0")
|
||
}
|
||
for name, addr := range map[string]string{
|
||
"syslog_listen_addr": Spec.Ingest.SyslogListenAddr,
|
||
"trap_listen_addr": Spec.Ingest.TrapListenAddr,
|
||
} {
|
||
addr = strings.TrimSpace(addr)
|
||
if addr == "" {
|
||
continue
|
||
}
|
||
if _, err := net.ResolveUDPAddr("udp", addr); err != nil {
|
||
return fmt.Errorf("Ingest.%s 无效: %w", name, err)
|
||
}
|
||
}
|
||
if Spec.AlertForward != nil && Spec.AlertForward.Enabled {
|
||
Spec.AlertForward.BaseURL = strings.TrimSpace(Spec.AlertForward.BaseURL)
|
||
Spec.AlertForward.InternalKey = strings.TrimSpace(Spec.AlertForward.InternalKey)
|
||
parsed, err := url.Parse(Spec.AlertForward.BaseURL)
|
||
if err != nil || parsed.Host == "" || (parsed.Scheme != "http" && parsed.Scheme != "https") {
|
||
return fmt.Errorf("AlertForward.base_url 必须是完整的 HTTP 或 HTTPS 地址")
|
||
}
|
||
if Spec.AlertForward.InternalKey == "" {
|
||
return fmt.Errorf("AlertForward.internal_key 不能为空")
|
||
}
|
||
}
|
||
return nil
|
||
}
|