feat: add update-token command to replace API token in-place

This commit is contained in:
Joel Male
2026-02-26 21:36:41 +10:00
parent 28a555c1de
commit 541c239b7e
2 changed files with 63 additions and 5 deletions
+1
View File
@@ -44,6 +44,7 @@ ## CLI Commands
```bash ```bash
sudo pulsewise-collector version # show version, check for updates sudo pulsewise-collector version # show version, check for updates
sudo pulsewise-collector update # download and install latest version sudo pulsewise-collector update # download and install latest version
sudo pulsewise-collector update-token <new-token> # replace the API token and restart
sudo pulsewise-collector status # show config, service state, last pulse sudo pulsewise-collector status # show config, service state, last pulse
sudo pulsewise-collector dump # print full metrics payload as JSON sudo pulsewise-collector dump # print full metrics payload as JSON
sudo pulsewise-collector uninstall # remove binary, config, and service sudo pulsewise-collector uninstall # remove binary, config, and service
+57
View File
@@ -241,6 +241,9 @@ func main() {
case "dump": case "dump":
runDumpCommand() runDumpCommand()
return return
case "update-token":
runUpdateTokenCommand()
return
} }
} }
@@ -395,6 +398,60 @@ func reexecWithSudo() {
} }
} }
func runUpdateTokenCommand() {
if os.Getuid() != 0 {
reexecWithSudo()
return
}
if len(os.Args) < 3 || strings.TrimSpace(os.Args[2]) == "" {
fmt.Fprintf(os.Stderr, "\n %sUsage:%s pulsewise-collector update-token <new-token>\n\n", ansiBold, ansiReset)
os.Exit(1)
}
newToken := strings.TrimSpace(os.Args[2])
// Resolve config path (same logic as loadConfigFromFile)
configPath := configFilePath
if _, err := os.Stat(configPath); os.IsNotExist(err) {
homeDir, _ := os.UserHomeDir()
if homeDir != "" {
local := filepath.Join(homeDir, ".config", "pulsewise-collector", "config")
if _, err := os.Stat(local); err == nil {
configPath = local
}
}
}
// Read existing config, replace TOKEN line
data, err := os.ReadFile(configPath)
if err != nil {
fmt.Fprintf(os.Stderr, "\n %sError:%s could not read config: %v\n\n", ansiRed, ansiReset, err)
os.Exit(1)
}
lines := strings.Split(string(data), "\n")
tokenFound := false
for i, line := range lines {
if strings.HasPrefix(strings.TrimSpace(line), "TOKEN=") {
lines[i] = "TOKEN=" + newToken
tokenFound = true
break
}
}
if !tokenFound {
// Prepend if TOKEN line is somehow missing
lines = append([]string{"TOKEN=" + newToken}, lines...)
}
if err := os.WriteFile(configPath, []byte(strings.Join(lines, "\n")), 0600); err != nil {
fmt.Fprintf(os.Stderr, "\n %sError:%s could not write config: %v\n\n", ansiRed, ansiReset, err)
os.Exit(1)
}
fmt.Printf("\n %sToken updated.%s\n", ansiGreen, ansiReset)
restartService()
}
func runStatusCommand() { func runStatusCommand() {
if os.Getuid() != 0 { if os.Getuid() != 0 {
reexecWithSudo() reexecWithSudo()