v0.5.0 removed tcp tls, basic auth hash changed to argon2, refactor
This commit is contained in:
@@ -29,7 +29,7 @@ type BasicAuthConfig struct {
|
||||
|
||||
type BasicAuthUser struct {
|
||||
Username string `toml:"username"`
|
||||
// Password hash (bcrypt)
|
||||
// Password hash (Argon2id)
|
||||
PasswordHash string `toml:"password_hash"`
|
||||
}
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@ import "fmt"
|
||||
|
||||
// Represents logging configuration for LogWisp
|
||||
type LogConfig struct {
|
||||
// Output mode: "file", "stdout", "stderr", "both", "none"
|
||||
// Output mode: "file", "stdout", "stderr", "split", "all", "none"
|
||||
Output string `toml:"output"`
|
||||
|
||||
// Log level: "debug", "info", "warn", "error"
|
||||
Level string `toml:"level"`
|
||||
|
||||
// File output settings (when Output includes "file" or "both")
|
||||
// File output settings (when Output includes "file" or "all")
|
||||
File *LogFileConfig `toml:"file"`
|
||||
|
||||
// Console output settings
|
||||
@@ -66,7 +66,7 @@ func DefaultLogConfig() *LogConfig {
|
||||
func validateLogConfig(cfg *LogConfig) error {
|
||||
validOutputs := map[string]bool{
|
||||
"file": true, "stdout": true, "stderr": true,
|
||||
"both": true, "all": true, "none": true,
|
||||
"split": true, "all": true, "none": true,
|
||||
}
|
||||
if !validOutputs[cfg.Output] {
|
||||
return fmt.Errorf("invalid log output mode: %s", cfg.Output)
|
||||
|
||||
@@ -131,8 +131,8 @@ func validateSource(pipelineName string, sourceIndex int, cfg *SourceConfig) err
|
||||
}
|
||||
|
||||
// Validate net_limit
|
||||
if rl, ok := cfg.Options["net_limit"].(map[string]any); ok {
|
||||
if err := validateNetLimitOptions("HTTP source", pipelineName, sourceIndex, rl); err != nil {
|
||||
if nl, ok := cfg.Options["net_limit"].(map[string]any); ok {
|
||||
if err := validateNetLimitOptions("HTTP source", pipelineName, sourceIndex, nl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -161,15 +161,8 @@ func validateSource(pipelineName string, sourceIndex int, cfg *SourceConfig) err
|
||||
}
|
||||
|
||||
// Validate net_limit
|
||||
if rl, ok := cfg.Options["net_limit"].(map[string]any); ok {
|
||||
if err := validateNetLimitOptions("TCP source", pipelineName, sourceIndex, rl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Validate TLS
|
||||
if tls, ok := cfg.Options["tls"].(map[string]any); ok {
|
||||
if err := validateTLSOptions("TCP source", pipelineName, sourceIndex, tls); err != nil {
|
||||
if nl, ok := cfg.Options["net_limit"].(map[string]any); ok {
|
||||
if err := validateNetLimitOptions("TCP source", pipelineName, sourceIndex, nl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -196,7 +189,7 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
pipelineName, sinkIndex)
|
||||
}
|
||||
|
||||
// Validate host if provided
|
||||
// Validate host
|
||||
if host, ok := cfg.Options["host"].(string); ok && host != "" {
|
||||
if net.ParseIP(host) == nil {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: invalid IP address: %s",
|
||||
@@ -219,7 +212,7 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
}
|
||||
}
|
||||
|
||||
// Validate paths if provided
|
||||
// Validate paths
|
||||
if streamPath, ok := cfg.Options["stream_path"].(string); ok {
|
||||
if !strings.HasPrefix(streamPath, "/") {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: stream path must start with /: %s",
|
||||
@@ -234,7 +227,7 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
}
|
||||
}
|
||||
|
||||
// Validate heartbeat if present
|
||||
// Validate heartbeat
|
||||
if hb, ok := cfg.Options["heartbeat"].(map[string]any); ok {
|
||||
if err := validateHeartbeatOptions("HTTP", pipelineName, sinkIndex, hb); err != nil {
|
||||
return err
|
||||
@@ -248,9 +241,9 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
}
|
||||
}
|
||||
|
||||
// Validate net limit if present
|
||||
if rl, ok := cfg.Options["net_limit"].(map[string]any); ok {
|
||||
if err := validateNetLimitOptions("HTTP", pipelineName, sinkIndex, rl); err != nil {
|
||||
// Validate net limit
|
||||
if nl, ok := cfg.Options["net_limit"].(map[string]any); ok {
|
||||
if err := validateNetLimitOptions("HTTP", pipelineName, sinkIndex, nl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -263,7 +256,7 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
pipelineName, sinkIndex)
|
||||
}
|
||||
|
||||
// Validate host if provided
|
||||
// Validate host
|
||||
if host, ok := cfg.Options["host"].(string); ok && host != "" {
|
||||
if net.ParseIP(host) == nil {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: invalid IP address: %s",
|
||||
@@ -286,23 +279,16 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
}
|
||||
}
|
||||
|
||||
// Validate heartbeat if present
|
||||
// Validate heartbeat
|
||||
if hb, ok := cfg.Options["heartbeat"].(map[string]any); ok {
|
||||
if err := validateHeartbeatOptions("TCP", pipelineName, sinkIndex, hb); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Validate TLS if present
|
||||
if tls, ok := cfg.Options["tls"].(map[string]any); ok {
|
||||
if err := validateTLSOptions("TCP", pipelineName, sinkIndex, tls); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Validate net limit if present
|
||||
if rl, ok := cfg.Options["net_limit"].(map[string]any); ok {
|
||||
if err := validateNetLimitOptions("TCP", pipelineName, sinkIndex, rl); err != nil {
|
||||
// Validate net limit
|
||||
if nl, ok := cfg.Options["net_limit"].(map[string]any); ok {
|
||||
if err := validateNetLimitOptions("TCP", pipelineName, sinkIndex, nl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,6 @@ type TCPConfig struct {
|
||||
Port int64 `toml:"port"`
|
||||
BufferSize int64 `toml:"buffer_size"`
|
||||
|
||||
// TLS Configuration
|
||||
TLS *TLSConfig `toml:"tls"`
|
||||
|
||||
// Net limiting
|
||||
NetLimit *NetLimitConfig `toml:"net_limit"`
|
||||
|
||||
@@ -63,16 +60,15 @@ type NetLimitConfig struct {
|
||||
// Burst size (token bucket)
|
||||
BurstSize int64 `toml:"burst_size"`
|
||||
|
||||
// Net limit by: "ip", "user", "token", "global"
|
||||
LimitBy string `toml:"limit_by"`
|
||||
|
||||
// Response when net limited
|
||||
ResponseCode int64 `toml:"response_code"` // Default: 429
|
||||
ResponseMessage string `toml:"response_message"` // Default: "Net limit exceeded"
|
||||
|
||||
// Connection limits
|
||||
MaxConnectionsPerIP int64 `toml:"max_connections_per_ip"`
|
||||
MaxTotalConnections int64 `toml:"max_total_connections"`
|
||||
MaxConnectionsPerIP int64 `toml:"max_connections_per_ip"`
|
||||
MaxConnectionsPerUser int64 `toml:"max_connections_per_user"`
|
||||
MaxConnectionsPerToken int64 `toml:"max_connections_per_token"`
|
||||
MaxConnectionsTotal int64 `toml:"max_connections_total"`
|
||||
}
|
||||
|
||||
func validateHeartbeatOptions(serverType, pipelineName string, sinkIndex int, hb map[string]any) error {
|
||||
@@ -93,13 +89,13 @@ func validateHeartbeatOptions(serverType, pipelineName string, sinkIndex int, hb
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateNetLimitOptions(serverType, pipelineName string, sinkIndex int, rl map[string]any) error {
|
||||
if enabled, ok := rl["enabled"].(bool); !ok || !enabled {
|
||||
func validateNetLimitOptions(serverType, pipelineName string, sinkIndex int, nl map[string]any) error {
|
||||
if enabled, ok := nl["enabled"].(bool); !ok || !enabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate IP lists if present
|
||||
if ipWhitelist, ok := rl["ip_whitelist"].([]any); ok {
|
||||
if ipWhitelist, ok := nl["ip_whitelist"].([]any); ok {
|
||||
for i, entry := range ipWhitelist {
|
||||
entryStr, ok := entry.(string)
|
||||
if !ok {
|
||||
@@ -112,7 +108,7 @@ func validateNetLimitOptions(serverType, pipelineName string, sinkIndex int, rl
|
||||
}
|
||||
}
|
||||
|
||||
if ipBlacklist, ok := rl["ip_blacklist"].([]any); ok {
|
||||
if ipBlacklist, ok := nl["ip_blacklist"].([]any); ok {
|
||||
for i, entry := range ipBlacklist {
|
||||
entryStr, ok := entry.(string)
|
||||
if !ok {
|
||||
@@ -126,30 +122,21 @@ func validateNetLimitOptions(serverType, pipelineName string, sinkIndex int, rl
|
||||
}
|
||||
|
||||
// Validate requests per second
|
||||
rps, ok := rl["requests_per_second"].(float64)
|
||||
rps, ok := nl["requests_per_second"].(float64)
|
||||
if !ok || rps <= 0 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: requests_per_second must be positive",
|
||||
pipelineName, sinkIndex, serverType)
|
||||
}
|
||||
|
||||
// Validate burst size
|
||||
burst, ok := rl["burst_size"].(int64)
|
||||
burst, ok := nl["burst_size"].(int64)
|
||||
if !ok || burst < 1 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: burst_size must be at least 1",
|
||||
pipelineName, sinkIndex, serverType)
|
||||
}
|
||||
|
||||
// Validate limit_by
|
||||
if limitBy, ok := rl["limit_by"].(string); ok && limitBy != "" {
|
||||
validLimitBy := map[string]bool{"ip": true, "global": true}
|
||||
if !validLimitBy[limitBy] {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: invalid limit_by value: %s (must be 'ip' or 'global')",
|
||||
pipelineName, sinkIndex, serverType, limitBy)
|
||||
}
|
||||
}
|
||||
|
||||
// Validate response code
|
||||
if respCode, ok := rl["response_code"].(int64); ok {
|
||||
if respCode, ok := nl["response_code"].(int64); ok {
|
||||
if respCode > 0 && (respCode < 400 || respCode >= 600) {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: response_code must be 4xx or 5xx: %d",
|
||||
pipelineName, sinkIndex, serverType, respCode)
|
||||
@@ -157,14 +144,25 @@ func validateNetLimitOptions(serverType, pipelineName string, sinkIndex int, rl
|
||||
}
|
||||
|
||||
// Validate connection limits
|
||||
maxPerIP, perIPOk := rl["max_connections_per_ip"].(int64)
|
||||
maxTotal, totalOk := rl["max_total_connections"].(int64)
|
||||
maxPerIP, perIPOk := nl["max_connections_per_ip"].(int64)
|
||||
maxPerUser, perUserOk := nl["max_connections_per_user"].(int64)
|
||||
maxPerToken, perTokenOk := nl["max_connections_per_token"].(int64)
|
||||
maxTotal, totalOk := nl["max_connections_total"].(int64)
|
||||
|
||||
if perIPOk && totalOk && maxPerIP > 0 && maxTotal > 0 {
|
||||
if perIPOk && perUserOk && perTokenOk && totalOk &&
|
||||
maxPerIP > 0 && maxPerUser > 0 && maxPerToken > 0 && maxTotal > 0 {
|
||||
if maxPerIP > maxTotal {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: max_connections_per_ip (%d) cannot exceed max_total_connections (%d)",
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: max_connections_per_ip (%d) cannot exceed max_connections_total (%d)",
|
||||
pipelineName, sinkIndex, serverType, maxPerIP, maxTotal)
|
||||
}
|
||||
if maxPerUser > maxTotal {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: max_connections_per_user (%d) cannot exceed max_connections_total (%d)",
|
||||
pipelineName, sinkIndex, serverType, maxPerUser, maxTotal)
|
||||
}
|
||||
if maxPerToken > maxTotal {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: max_connections_per_token (%d) cannot exceed max_connections_total (%d)",
|
||||
pipelineName, sinkIndex, serverType, maxPerToken, maxTotal)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user