mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-12 10:16:37 +08:00
fix lint
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package uptimekuma provides a Socket.IO client and sync implementation for Uptime Kuma.
|
||||
package uptimekuma
|
||||
|
||||
import (
|
||||
@@ -16,28 +17,30 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// UptimeKumaMonitor represents a monitor entry from Uptime Kuma.
|
||||
type UptimeKumaMonitor struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Url string `json:"url"`
|
||||
Type string `json:"type"`
|
||||
Interval int `json:"interval"`
|
||||
MaxRetries int `json:"maxretries"`
|
||||
RetryInterval int `json:"retryInterval"`
|
||||
Timeout int `json:"timeout"`
|
||||
Tags []UptimeKumaTag `json:"tags"`
|
||||
const emitAckTimeout = 10 * time.Second
|
||||
|
||||
// Monitor represents a monitor entry from Uptime Kuma.
|
||||
type Monitor struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
Type string `json:"type"`
|
||||
Interval int `json:"interval"`
|
||||
MaxRetries int `json:"maxretries"`
|
||||
RetryInterval int `json:"retryInterval"`
|
||||
Timeout int `json:"timeout"`
|
||||
Tags []Tag `json:"tags"`
|
||||
}
|
||||
|
||||
// UptimeKumaTag represents a tag attached to a monitor.
|
||||
type UptimeKumaTag struct {
|
||||
// Tag represents a tag attached to a monitor.
|
||||
type Tag struct {
|
||||
ID int `json:"tag_id"`
|
||||
Name string `json:"name"`
|
||||
Color string `json:"color"`
|
||||
}
|
||||
|
||||
// UptimeKumaTagItem represents a tag returned by getTags.
|
||||
type UptimeKumaTagItem struct {
|
||||
// TagItem represents a tag returned by getTags.
|
||||
type TagItem struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Color string `json:"color"`
|
||||
@@ -55,7 +58,7 @@ type SocketIOClient struct {
|
||||
closeOnce sync.Once
|
||||
|
||||
monitorListMutex sync.RWMutex
|
||||
monitorList map[string]UptimeKumaMonitor
|
||||
monitorList map[string]Monitor
|
||||
monitorListChan chan struct{}
|
||||
monitorListOnce sync.Once
|
||||
|
||||
@@ -76,7 +79,7 @@ func NewSocketIOClient(baseURL string) *SocketIOClient {
|
||||
ackChanMap: make(map[int]chan string),
|
||||
doneChan: make(chan struct{}),
|
||||
monitorListChan: make(chan struct{}),
|
||||
monitorList: make(map[string]UptimeKumaMonitor),
|
||||
monitorList: make(map[string]Monitor),
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
}
|
||||
@@ -95,7 +98,7 @@ func (c *SocketIOClient) Connect() error {
|
||||
slog.Error("Uptime Kuma handshake connection failed", "url", u, "error", err)
|
||||
return fmt.Errorf("handshake request failed: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
bs, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
@@ -130,7 +133,7 @@ func (c *SocketIOClient) Connect() error {
|
||||
slog.Error("Uptime Kuma namespace connect request failed", "sid", c.sid, "error", err)
|
||||
return fmt.Errorf("namespace connect failed: %w", err)
|
||||
}
|
||||
respConnect.Body.Close()
|
||||
_ = respConnect.Body.Close()
|
||||
slog.Debug("Namespace connected successfully to Uptime Kuma", "sid", c.sid)
|
||||
|
||||
go c.pollLoop()
|
||||
@@ -164,7 +167,7 @@ func (c *SocketIOClient) pollLoop() {
|
||||
}
|
||||
|
||||
bs, err := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
_ = resp.Body.Close()
|
||||
if err != nil {
|
||||
slog.Error("Failed to read Uptime Kuma polling body", "sid", c.sid, "error", err)
|
||||
c.err = err
|
||||
@@ -218,7 +221,7 @@ func (c *SocketIOClient) sendPong() {
|
||||
req.Header.Set("Content-Type", "text/plain;charset=UTF-8")
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err == nil {
|
||||
resp.Body.Close()
|
||||
_ = resp.Body.Close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +235,7 @@ func (c *SocketIOClient) handleEvent(payload string) {
|
||||
return
|
||||
}
|
||||
if eventName == "monitorList" {
|
||||
var list map[string]UptimeKumaMonitor
|
||||
var list map[string]Monitor
|
||||
if err := json.Unmarshal(arr[1], &list); err == nil {
|
||||
c.monitorListMutex.Lock()
|
||||
c.monitorList = list
|
||||
@@ -309,13 +312,13 @@ func (c *SocketIOClient) Emit(event string, args ...any) (string, error) {
|
||||
slog.Error("Failed to send Emit request", "event", event, "ackID", id, "error", err)
|
||||
return "", err
|
||||
}
|
||||
resp.Body.Close()
|
||||
_ = resp.Body.Close()
|
||||
|
||||
select {
|
||||
case result := <-ch:
|
||||
slog.Debug("Received Ack for event", "event", event, "ackID", id, "response", result)
|
||||
return result, nil
|
||||
case <-time.After(10 * time.Second):
|
||||
case <-time.After(emitAckTimeout):
|
||||
c.ackMutex.Lock()
|
||||
delete(c.ackChanMap, id)
|
||||
c.ackMutex.Unlock()
|
||||
@@ -344,11 +347,11 @@ func (c *SocketIOClient) GetMonitorListChan() <-chan struct{} {
|
||||
}
|
||||
|
||||
// GetMonitorList returns a copy of the current monitor list.
|
||||
func (c *SocketIOClient) GetMonitorList() map[string]UptimeKumaMonitor {
|
||||
func (c *SocketIOClient) GetMonitorList() map[string]Monitor {
|
||||
c.monitorListMutex.RLock()
|
||||
defer c.monitorListMutex.RUnlock()
|
||||
|
||||
m := make(map[string]UptimeKumaMonitor, len(c.monitorList))
|
||||
m := make(map[string]Monitor, len(c.monitorList))
|
||||
for k, v := range c.monitorList {
|
||||
m[k] = v
|
||||
}
|
||||
@@ -372,7 +375,7 @@ func ParseAckResponse(response string, target any) error {
|
||||
if errMsg == "" {
|
||||
errMsg = "unknown error from Uptime Kuma"
|
||||
}
|
||||
return fmt.Errorf("Uptime Kuma error response: %s", errMsg)
|
||||
return fmt.Errorf("uptime Kuma error response: %s", errMsg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,17 +10,18 @@ import (
|
||||
"log/slog"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/Rain-kl/Wavelet/internal/model"
|
||||
)
|
||||
|
||||
const uptimeKumaTagOpenFlare = "OpenFlare"
|
||||
|
||||
var isSyncing atomic.Bool
|
||||
|
||||
// SyncToUptimeKuma synchronizes enabled proxy routes to Uptime Kuma monitors.
|
||||
func SyncToUptimeKuma(ctx context.Context) error {
|
||||
if !model.UptimeKumaEnabled {
|
||||
return fmt.Errorf("Uptime Kuma integration is disabled")
|
||||
return fmt.Errorf("uptime Kuma integration is disabled")
|
||||
}
|
||||
|
||||
if !isSyncing.CompareAndSwap(false, true) {
|
||||
@@ -28,14 +29,9 @@ func SyncToUptimeKuma(ctx context.Context) error {
|
||||
}
|
||||
defer isSyncing.Store(false)
|
||||
|
||||
kumaURL := strings.TrimSpace(model.UptimeKumaUrl)
|
||||
kumaUsername := strings.TrimSpace(model.UptimeKumaUsername)
|
||||
kumaPassword := strings.TrimSpace(model.UptimeKumaPassword)
|
||||
if kumaURL == "" || kumaUsername == "" || kumaPassword == "" {
|
||||
return fmt.Errorf(
|
||||
"Uptime Kuma URL, username, or password is not configured (URL: %q, Username: %q, PasswordLength: %d)",
|
||||
kumaURL, kumaUsername, len(kumaPassword),
|
||||
)
|
||||
kumaURL, kumaUsername, kumaPassword, err := validateUptimeKumaConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
slog.Info("Starting Uptime Kuma sync process",
|
||||
@@ -54,88 +50,20 @@ func SyncToUptimeKuma(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
slog.Debug("Connecting to Uptime Kuma socket endpoint", "url", kumaURL)
|
||||
client := NewSocketIOClient(kumaURL)
|
||||
if err := client.Connect(); err != nil {
|
||||
slog.Error("Failed to connect to Uptime Kuma endpoint", "url", kumaURL, "error", err)
|
||||
return fmt.Errorf("failed to connect to Uptime Kuma: %w", err)
|
||||
client, err := connectAndLoginUptimeKuma(kumaURL, kumaUsername, kumaPassword)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
slog.Debug("Sending login request to Uptime Kuma", "username", kumaUsername)
|
||||
loginPayload := map[string]string{
|
||||
"username": kumaUsername,
|
||||
"password": kumaPassword,
|
||||
}
|
||||
loginAck, err := client.Emit("login", loginPayload)
|
||||
if err != nil {
|
||||
slog.Error("Failed to send login request to Uptime Kuma", "username", kumaUsername, "error", err)
|
||||
return fmt.Errorf("login request failed: %w", err)
|
||||
}
|
||||
|
||||
var loginResult struct {
|
||||
Ok bool `json:"ok"`
|
||||
}
|
||||
if err := ParseAckResponse(loginAck, &loginResult); err != nil || !loginResult.Ok {
|
||||
slog.Error("Uptime Kuma login verification failed", "username", kumaUsername, "error", err)
|
||||
return fmt.Errorf("login failed: %w", err)
|
||||
}
|
||||
slog.Debug("Successfully logged into Uptime Kuma", "username", kumaUsername)
|
||||
|
||||
slog.Debug("Waiting for monitor list push from Uptime Kuma")
|
||||
select {
|
||||
case <-client.GetMonitorListChan():
|
||||
slog.Debug("Received monitor list from Uptime Kuma")
|
||||
case <-time.After(5 * time.Second):
|
||||
slog.Error("Timeout waiting for Uptime Kuma monitorList push event")
|
||||
return fmt.Errorf("timeout waiting for monitorList event from Uptime Kuma")
|
||||
}
|
||||
|
||||
openFlareTagID, err := ensureOpenFlareTag(client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
existingOpenFlareMonitors := filterOpenFlareMonitors(client.GetMonitorList(), openFlareTagID)
|
||||
expectedSitesMap := make(map[string]bool)
|
||||
|
||||
for _, route := range expectedRoutes {
|
||||
expectedSitesMap[route.SiteName] = true
|
||||
targetURL, urlErr := routeMonitorURL(route)
|
||||
if urlErr != nil {
|
||||
slog.Error("Failed to resolve monitor URL", "name", route.SiteName, "error", urlErr)
|
||||
continue
|
||||
}
|
||||
|
||||
existing, exists := existingOpenFlareMonitors[route.SiteName]
|
||||
if !exists {
|
||||
if err := createMonitor(client, route.SiteName, targetURL, openFlareTagID); err != nil {
|
||||
slog.Error("Failed to add monitor to Uptime Kuma", "name", route.SiteName, "error", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if monitorNeedsUpdate(existing, targetURL) {
|
||||
if err := updateMonitor(client, existing.ID, route.SiteName, targetURL); err != nil {
|
||||
slog.Error("Failed to edit monitor in Uptime Kuma", "name", route.SiteName, "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for name, monitor := range existingOpenFlareMonitors {
|
||||
if expectedSitesMap[name] {
|
||||
continue
|
||||
}
|
||||
slog.Info("Deleting monitor in Uptime Kuma", "name", name, "monitorID", monitor.ID)
|
||||
deleteAck, err := client.Emit("deleteMonitor", monitor.ID)
|
||||
if err != nil {
|
||||
slog.Error("Failed to delete monitor in Uptime Kuma", "name", name, "monitorID", monitor.ID, "error", err)
|
||||
continue
|
||||
}
|
||||
if err := ParseAckResponse(deleteAck, nil); err != nil {
|
||||
slog.Error("Failed to parse delete monitor result", "name", name, "monitorID", monitor.ID, "error", err)
|
||||
}
|
||||
}
|
||||
expectedSitesMap := syncRouteMonitors(client, expectedRoutes, existingOpenFlareMonitors, openFlareTagID)
|
||||
removeStaleMonitors(client, existingOpenFlareMonitors, expectedSitesMap)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -178,8 +106,8 @@ func ensureOpenFlareTag(client *SocketIOClient) (int, error) {
|
||||
}
|
||||
|
||||
var tagsResult struct {
|
||||
Ok bool `json:"ok"`
|
||||
Tags []UptimeKumaTagItem `json:"tags"`
|
||||
Ok bool `json:"ok"`
|
||||
Tags []TagItem `json:"tags"`
|
||||
}
|
||||
if err := ParseAckResponse(tagsAck, &tagsResult); err != nil {
|
||||
slog.Error("Failed to parse tags response from Uptime Kuma", "error", err)
|
||||
@@ -187,7 +115,7 @@ func ensureOpenFlareTag(client *SocketIOClient) (int, error) {
|
||||
}
|
||||
|
||||
for _, tag := range tagsResult.Tags {
|
||||
if tag.Name == "OpenFlare" {
|
||||
if tag.Name == uptimeKumaTagOpenFlare {
|
||||
slog.Debug("Found existing OpenFlare tag", "tag_id", tag.ID)
|
||||
return tag.ID, nil
|
||||
}
|
||||
@@ -195,7 +123,7 @@ func ensureOpenFlareTag(client *SocketIOClient) (int, error) {
|
||||
|
||||
slog.Debug("OpenFlare tag not found, creating new tag")
|
||||
addTagAck, err := client.Emit("addTag", map[string]string{
|
||||
"name": "OpenFlare",
|
||||
"name": uptimeKumaTagOpenFlare,
|
||||
"color": "#4f46e5",
|
||||
})
|
||||
if err != nil {
|
||||
@@ -218,12 +146,12 @@ func ensureOpenFlareTag(client *SocketIOClient) (int, error) {
|
||||
return tagResult.Tag.ID, nil
|
||||
}
|
||||
|
||||
func filterOpenFlareMonitors(monitors map[string]UptimeKumaMonitor, openFlareTagID int) map[string]UptimeKumaMonitor {
|
||||
existingOpenFlareMonitors := make(map[string]UptimeKumaMonitor)
|
||||
func filterOpenFlareMonitors(monitors map[string]Monitor, openFlareTagID int) map[string]Monitor {
|
||||
existingOpenFlareMonitors := make(map[string]Monitor)
|
||||
for _, monitor := range monitors {
|
||||
hasOpenFlareTag := false
|
||||
for _, tag := range monitor.Tags {
|
||||
if tag.Name == "OpenFlare" || tag.ID == openFlareTagID {
|
||||
if tag.Name == uptimeKumaTagOpenFlare || tag.ID == openFlareTagID {
|
||||
hasOpenFlareTag = true
|
||||
break
|
||||
}
|
||||
@@ -295,8 +223,8 @@ func monitorPayload(id int, name, targetURL string) map[string]any {
|
||||
return payload
|
||||
}
|
||||
|
||||
func monitorNeedsUpdate(existing UptimeKumaMonitor, targetURL string) bool {
|
||||
return existing.Url != targetURL ||
|
||||
func monitorNeedsUpdate(existing Monitor, targetURL string) bool {
|
||||
return existing.URL != targetURL ||
|
||||
existing.Interval != model.UptimeKumaInterval ||
|
||||
existing.MaxRetries != model.UptimeKumaRetry ||
|
||||
existing.RetryInterval != model.UptimeKumaRetryInterval ||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package uptimekuma
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Rain-kl/Wavelet/internal/model"
|
||||
)
|
||||
|
||||
const monitorListWaitTimeout = 5 * time.Second
|
||||
|
||||
func validateUptimeKumaConfig() (string, string, string, error) {
|
||||
kumaURL := strings.TrimSpace(model.UptimeKumaURL)
|
||||
kumaUsername := strings.TrimSpace(model.UptimeKumaUsername)
|
||||
kumaPassword := strings.TrimSpace(model.UptimeKumaPassword)
|
||||
if kumaURL == "" || kumaUsername == "" || kumaPassword == "" {
|
||||
return kumaURL, kumaUsername, kumaPassword, fmt.Errorf(
|
||||
"uptime Kuma URL, username, or password is not configured (URL: %q, Username: %q, PasswordLength: %d)",
|
||||
kumaURL, kumaUsername, len(kumaPassword),
|
||||
)
|
||||
}
|
||||
return kumaURL, kumaUsername, kumaPassword, nil
|
||||
}
|
||||
|
||||
func connectAndLoginUptimeKuma(kumaURL, kumaUsername, kumaPassword string) (*SocketIOClient, error) {
|
||||
slog.Debug("Connecting to Uptime Kuma socket endpoint", "url", kumaURL)
|
||||
client := NewSocketIOClient(kumaURL)
|
||||
if err := client.Connect(); err != nil {
|
||||
slog.Error("Failed to connect to Uptime Kuma endpoint", "url", kumaURL, "error", err)
|
||||
return nil, fmt.Errorf("failed to connect to Uptime Kuma: %w", err)
|
||||
}
|
||||
|
||||
slog.Debug("Sending login request to Uptime Kuma", "username", kumaUsername)
|
||||
loginAck, err := client.Emit("login", map[string]string{
|
||||
"username": kumaUsername,
|
||||
"password": kumaPassword,
|
||||
})
|
||||
if err != nil {
|
||||
client.Close()
|
||||
slog.Error("Failed to send login request to Uptime Kuma", "username", kumaUsername, "error", err)
|
||||
return nil, fmt.Errorf("login request failed: %w", err)
|
||||
}
|
||||
|
||||
var loginResult struct {
|
||||
Ok bool `json:"ok"`
|
||||
}
|
||||
if err := ParseAckResponse(loginAck, &loginResult); err != nil || !loginResult.Ok {
|
||||
client.Close()
|
||||
slog.Error("Uptime Kuma login verification failed", "username", kumaUsername, "error", err)
|
||||
return nil, fmt.Errorf("login failed: %w", err)
|
||||
}
|
||||
slog.Debug("Successfully logged into Uptime Kuma", "username", kumaUsername)
|
||||
|
||||
slog.Debug("Waiting for monitor list push from Uptime Kuma")
|
||||
select {
|
||||
case <-client.GetMonitorListChan():
|
||||
slog.Debug("Received monitor list from Uptime Kuma")
|
||||
case <-time.After(monitorListWaitTimeout):
|
||||
client.Close()
|
||||
slog.Error("Timeout waiting for Uptime Kuma monitorList push event")
|
||||
return nil, fmt.Errorf("timeout waiting for monitorList event from Uptime Kuma")
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func syncRouteMonitors(client *SocketIOClient, expectedRoutes []*model.ProxyRoute, existingMonitors map[string]Monitor, openFlareTagID int) map[string]bool {
|
||||
expectedSitesMap := make(map[string]bool, len(expectedRoutes))
|
||||
for _, route := range expectedRoutes {
|
||||
expectedSitesMap[route.SiteName] = true
|
||||
targetURL, urlErr := routeMonitorURL(route)
|
||||
if urlErr != nil {
|
||||
slog.Error("Failed to resolve monitor URL", "name", route.SiteName, "error", urlErr)
|
||||
continue
|
||||
}
|
||||
|
||||
existing, exists := existingMonitors[route.SiteName]
|
||||
if !exists {
|
||||
if err := createMonitor(client, route.SiteName, targetURL, openFlareTagID); err != nil {
|
||||
slog.Error("Failed to add monitor to Uptime Kuma", "name", route.SiteName, "error", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if monitorNeedsUpdate(existing, targetURL) {
|
||||
if err := updateMonitor(client, existing.ID, route.SiteName, targetURL); err != nil {
|
||||
slog.Error("Failed to edit monitor in Uptime Kuma", "name", route.SiteName, "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return expectedSitesMap
|
||||
}
|
||||
|
||||
func removeStaleMonitors(client *SocketIOClient, existingMonitors map[string]Monitor, expectedSitesMap map[string]bool) {
|
||||
for name, monitor := range existingMonitors {
|
||||
if expectedSitesMap[name] {
|
||||
continue
|
||||
}
|
||||
slog.Info("Deleting monitor in Uptime Kuma", "name", name, "monitorID", monitor.ID)
|
||||
deleteAck, err := client.Emit("deleteMonitor", monitor.ID)
|
||||
if err != nil {
|
||||
slog.Error("Failed to delete monitor in Uptime Kuma", "name", name, "monitorID", monitor.ID, "error", err)
|
||||
continue
|
||||
}
|
||||
if err := ParseAckResponse(deleteAck, nil); err != nil {
|
||||
slog.Error("Failed to parse delete monitor result", "name", name, "monitorID", monitor.ID, "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,7 @@ func setupSyncTestDB(t *testing.T) func() {
|
||||
|
||||
func backupUptimeKumaConfig() func() {
|
||||
oldEnabled := model.UptimeKumaEnabled
|
||||
oldURL := model.UptimeKumaUrl
|
||||
oldURL := model.UptimeKumaURL
|
||||
oldUsername := model.UptimeKumaUsername
|
||||
oldPassword := model.UptimeKumaPassword
|
||||
oldScope := model.UptimeKumaMonitorScope
|
||||
@@ -143,7 +143,7 @@ func backupUptimeKumaConfig() func() {
|
||||
|
||||
return func() {
|
||||
model.UptimeKumaEnabled = oldEnabled
|
||||
model.UptimeKumaUrl = oldURL
|
||||
model.UptimeKumaURL = oldURL
|
||||
model.UptimeKumaUsername = oldUsername
|
||||
model.UptimeKumaPassword = oldPassword
|
||||
model.UptimeKumaMonitorScope = oldScope
|
||||
@@ -228,7 +228,7 @@ func TestSyncToUptimeKumaSuccess(t *testing.T) {
|
||||
defer server.Close()
|
||||
|
||||
model.UptimeKumaEnabled = true
|
||||
model.UptimeKumaUrl = server.URL
|
||||
model.UptimeKumaURL = server.URL
|
||||
model.UptimeKumaUsername = "admin"
|
||||
model.UptimeKumaPassword = "password"
|
||||
model.UptimeKumaMonitorScope = "all"
|
||||
@@ -313,7 +313,7 @@ func TestSyncToUptimeKumaSelectedScope(t *testing.T) {
|
||||
defer server.Close()
|
||||
|
||||
model.UptimeKumaEnabled = true
|
||||
model.UptimeKumaUrl = server.URL
|
||||
model.UptimeKumaURL = server.URL
|
||||
model.UptimeKumaUsername = "admin"
|
||||
model.UptimeKumaPassword = "password"
|
||||
model.UptimeKumaMonitorScope = "selected"
|
||||
|
||||
Reference in New Issue
Block a user