aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-01-19 17:57:19 -0800
committerFuwn <[email protected]>2026-01-19 17:57:19 -0800
commit839611b177c4b253f6a55566dd6aaff4b8931d7f (patch)
tree4f4ca859849d298a34844cdefe1c6ae7c85730fc
parentfeat: Add configurable user_agent to bypass bot detection (diff)
downloadkaze-839611b177c4b253f6a55566dd6aaff4b8931d7f.tar.xz
kaze-839611b177c4b253f6a55566dd6aaff4b8931d7f.zip
fix: Preserve config formatting when updating reset flag
Use line-based approach instead of YAML unmarshal/marshal to prevent config file rewriting with zero values. This ensures monitors that omit fields like interval and timeout continue to inherit from group defaults.
-rw-r--r--internal/config/config.go75
1 files changed, 53 insertions, 22 deletions
diff --git a/internal/config/config.go b/internal/config/config.go
index 4d428fc..5a173b6 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -3,6 +3,7 @@ package config
import (
"fmt"
"os"
+ "strings"
"time"
"gopkg.in/yaml.v3"
@@ -350,6 +351,7 @@ type MonitorWithGroup struct {
}
// UpdateResetFlag updates the reset_on_next_check flag for a specific monitor in the config file
+// Uses a line-based approach to preserve original formatting and omitted fields
func UpdateResetFlag(configPath string, monitorName string, value bool) error {
// Read the config file
data, err := os.ReadFile(configPath)
@@ -357,38 +359,67 @@ func UpdateResetFlag(configPath string, monitorName string, value bool) error {
return fmt.Errorf("failed to read config file: %w", err)
}
- // Parse as YAML
- var cfg Config
- if err := yaml.Unmarshal(data, &cfg); err != nil {
- return fmt.Errorf("failed to parse config file: %w", err)
- }
+ lines := strings.Split(string(data), "\n")
+ inMonitor := false
+ monitorIndent := ""
+ foundMonitor := false
+
+ for i := 0; i < len(lines); i++ {
+ line := lines[i]
+ trimmed := strings.TrimSpace(line)
+
+ // Check if this is the start of our target monitor
+ if strings.HasPrefix(trimmed, "- name:") || strings.HasPrefix(trimmed, "name:") {
+ // Extract monitor name from line
+ namePart := strings.TrimPrefix(trimmed, "- name:")
+ namePart = strings.TrimPrefix(namePart, "name:")
+ namePart = strings.TrimSpace(namePart)
+ namePart = strings.Trim(namePart, "\"'")
+
+ if namePart == monitorName {
+ inMonitor = true
+ foundMonitor = true
+ // Calculate the indentation level
+ monitorIndent = line[:len(line)-len(strings.TrimLeft(line, " \t"))]
+ continue
+ }
+ }
- // Find and update the monitor
- found := false
- for i := range cfg.Groups {
- for j := range cfg.Groups[i].Monitors {
- if cfg.Groups[i].Monitors[j].Name == monitorName {
- cfg.Groups[i].Monitors[j].ResetOnNextCheck = value
- found = true
+ // If we're in the target monitor, look for reset_on_next_check or end of monitor
+ if inMonitor {
+ // Check if we've left the monitor section (new monitor or less indented line)
+ if strings.HasPrefix(trimmed, "- name:") || strings.HasPrefix(trimmed, "name:") {
+ // We've reached another monitor without finding reset_on_next_check
+ // Insert the line before this one if we're setting to false
+ if !value {
+ // Only add if setting to false (after a reset)
+ insertLine := monitorIndent + " reset_on_next_check: false"
+ lines = append(lines[:i], append([]string{insertLine}, lines[i:]...)...)
+ }
+ break
+ }
+
+ // Check if this line is reset_on_next_check
+ if strings.Contains(trimmed, "reset_on_next_check:") {
+ // Update the value
+ if !value {
+ // Set to false after reset
+ lines[i] = monitorIndent + " reset_on_next_check: false"
+ } else {
+ // Keep as true (should already be true, but update to be sure)
+ lines[i] = monitorIndent + " reset_on_next_check: true"
+ }
break
}
- }
- if found {
- break
}
}
- if !found {
+ if !foundMonitor {
return fmt.Errorf("monitor %q not found in config", monitorName)
}
- // Marshal back to YAML
- newData, err := yaml.Marshal(&cfg)
- if err != nil {
- return fmt.Errorf("failed to marshal config: %w", err)
- }
-
// Write back to file
+ newData := []byte(strings.Join(lines, "\n"))
if err := os.WriteFile(configPath, newData, 0644); err != nil {
return fmt.Errorf("failed to write config file: %w", err)
}