From 05399c1f86aa362e9a8707f8b2517f8c03f737d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E9=87=91=E8=99=8E?= <1050780355@qq.com> Date: Fri, 6 Dec 2024 16:16:26 +0800 Subject: [PATCH] Add monitor info (#5267) * add database feishu info and cockroach monitor --- service/exceptionmonitor/api/api.go | 64 ++++- service/exceptionmonitor/dao/init.go | 3 +- service/exceptionmonitor/go.mod | 7 +- service/exceptionmonitor/go.sum | 2 + .../helper/monitor/cockroachdb_monitor.go | 54 ++++ .../helper/monitor/database_backup_monitor.go | 11 +- .../helper/monitor/database_monitor.go | 233 ++++++++++-------- .../monitor/database_performance_monitor.go | 82 +++--- .../helper/monitor/performance.go | 10 +- .../helper/monitor/quota_monitor.go | 11 +- .../helper/notification/desktop.go | 10 +- .../helper/notification/feishu.go | 148 +++++++---- .../helper/notification/sms.go | 6 +- service/exceptionmonitor/main.go | 1 + service/go.work.sum | 103 ++++++++ 15 files changed, 512 insertions(+), 233 deletions(-) create mode 100644 service/exceptionmonitor/helper/monitor/cockroachdb_monitor.go diff --git a/service/exceptionmonitor/api/api.go b/service/exceptionmonitor/api/api.go index 1bc49255969..f430f714005 100644 --- a/service/exceptionmonitor/api/api.go +++ b/service/exceptionmonitor/api/api.go @@ -22,25 +22,63 @@ type QueryResult struct { } `json:"data"` } +type Info struct { + // lastStatus、recoveryStatus、lastStatusTime、recoveryStatusTime、lastStatusInfo、recoveryStatusInfo + //todo 是否应该分几个状态,是否有状态不正确的地方 + DatabaseClusterName string + Namespace string + DebtLevel string + DatabaseType string + Events string + Reason string + NotificationType string + DiskUsage string + CPUUsage string + MemUsage string + PerformanceType string + ExceptionType string + ExceptionStatus string + RecoveryStatus string + ExceptionStatusTime string + RecoveryTime string + DatabaseClusterUID string + FeishuWebHook string + //struct + FeishuInfo []map[string]interface{} +} + +type NameSpaceQuota struct { + NameSpace string + CPULimit string + MemLimit string + GPULimit string + EphemeralStorageLimit string + ObjectStorageLimit string + NodePortLimit string + StorageLimit string + CPUUsage string + MemUsage string + GPUUsage string + EphemeralStorageUsage string + ObjectStorageUsage string + NodePortUsage string + StorageUsage string +} + const ( StatusDeleting = "Deleting" StatusCreating = "Creating" StatusStopping = "Stopping" StatusStopped = "Stopped" StatusRunning = "Running" - StatusUpdating = "Updating" + //StatusUpdating = "Updating" StatusUnknown = "" MonitorTypeALL = "all" ) var ( - ClientSet *kubernetes.Clientset - DynamicClient *dynamic.DynamicClient - // records the last database status - LastDatabaseClusterStatus = make(map[string]string) - // record the debt ns - ExceptionDatabaseMap = make(map[string]bool) - FeishuWebHookMap = make(map[string]string) + ClientSet *kubernetes.Clientset + DynamicClient *dynamic.DynamicClient DebtNamespaceMap = make(map[string]bool) DiskFullNamespaceMap = make(map[string]bool) DiskMonitorNamespaceMap = make(map[string]bool) @@ -48,7 +86,7 @@ var ( MemMonitorNamespaceMap = make(map[string]bool) LastBackupStatusMap = make(map[string]string) IsSendBackupStatusMap = make(map[string]string) - DatabaseNamespaceMap = make(map[string]string) + DatabaseNotificationInfoMap = make(map[string]*Info) ExceededQuotaException = "exceeded quota" DiskException = "Writing to log file failed" OwnerLabel = "user.sealos.io/owner" @@ -65,6 +103,7 @@ var ( CPUMemMonitor bool BackupMonitor bool QuotaMonitor bool + CockroachMonitor bool DatabaseDiskMonitorThreshold float64 DatabaseExceptionMonitorThreshold float64 DatabaseCPUMonitorThreshold float64 @@ -72,6 +111,8 @@ var ( QuotaThreshold float64 APPID string APPSECRET string + GlobalCockroachURI string + LocalCockroachURI string DatabaseStatusMessageIDMap = make(map[string]string) DatabaseDiskMessageIDMap = make(map[string]string) DatabaseCPUMessageIDMap = make(map[string]string) @@ -90,11 +131,14 @@ func GetENV() error { MonitorType = getEnvWithCheck("MonitorType", &missingEnvVars) clusterNS := getEnvWithCheck("ClusterNS", &missingEnvVars) LOCALREGION = getEnvWithCheck("LOCALREGION", &missingEnvVars) + GlobalCockroachURI = getEnvWithCheck("GlobalCockroachURI", &missingEnvVars) + LocalCockroachURI = getEnvWithCheck("LocalCockroachURI", &missingEnvVars) DatabaseMonitor, _ = strconv.ParseBool(getEnvWithCheck("DatabaseMonitor", &missingEnvVars)) DiskMonitor, _ = strconv.ParseBool(getEnvWithCheck("DiskMonitor", &missingEnvVars)) CPUMemMonitor, _ = strconv.ParseBool(getEnvWithCheck("CPUMemMonitor", &missingEnvVars)) BackupMonitor, _ = strconv.ParseBool(getEnvWithCheck("BackupMonitor", &missingEnvVars)) QuotaMonitor, _ = strconv.ParseBool(getEnvWithCheck("QuotaMonitor", &missingEnvVars)) + CockroachMonitor, _ = strconv.ParseBool(getEnvWithCheck("CockroachMonitor", &missingEnvVars)) DatabaseDiskMonitorThreshold, _ = strconv.ParseFloat(getEnvWithCheck("DatabaseDiskMonitorThreshold", &missingEnvVars), 64) DatabaseExceptionMonitorThreshold, _ = strconv.ParseFloat(getEnvWithCheck("DatabaseExceptionMonitorThreshold", &missingEnvVars), 64) DatabaseCPUMonitorThreshold, _ = strconv.ParseFloat(getEnvWithCheck("DatabaseCPUMonitorThreshold", &missingEnvVars), 64) @@ -119,6 +163,8 @@ func GetENV() error { "FeishuWebhookURLBackup", //Quota "FeishuWebhookURLQuota", + //CockroachDB + "FeishuWebhookURLCockroachDB", }, FeishuWebhookURLMap, &missingEnvVars) // Get ClusterRegionMap diff --git a/service/exceptionmonitor/dao/init.go b/service/exceptionmonitor/dao/init.go index e865536e75f..8215c6fb284 100644 --- a/service/exceptionmonitor/dao/init.go +++ b/service/exceptionmonitor/dao/init.go @@ -3,9 +3,8 @@ package dao import ( "os" - "github.com/labring/sealos/service/exceptionmonitor/api" - "github.com/labring/sealos/controllers/pkg/database/cockroach" + "github.com/labring/sealos/service/exceptionmonitor/api" ) var ( diff --git a/service/exceptionmonitor/go.mod b/service/exceptionmonitor/go.mod index c3b3589e9e7..dcfc8c233d8 100644 --- a/service/exceptionmonitor/go.mod +++ b/service/exceptionmonitor/go.mod @@ -31,7 +31,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect @@ -41,6 +41,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/larksuite/oapi-sdk-go/v3 v3.2.9 // indirect + github.com/lib/pq v1.10.9 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/matoous/go-nanoid/v2 v2.0.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -51,7 +52,7 @@ require ( go.mongodb.org/mongo-driver v1.12.1 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/net v0.23.0 // indirect - golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/oauth2 v0.12.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect @@ -70,7 +71,7 @@ require ( k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) replace ( diff --git a/service/exceptionmonitor/go.sum b/service/exceptionmonitor/go.sum index 90fef7e8a9f..2aa954a8fde 100644 --- a/service/exceptionmonitor/go.sum +++ b/service/exceptionmonitor/go.sum @@ -99,6 +99,8 @@ github.com/larksuite/oapi-sdk-go v1.1.48 h1:RHRr5LW68AibBzXVRXObUpkbS6TXapl4TAyh github.com/larksuite/oapi-sdk-go v1.1.48/go.mod h1:7ybKAbVdKBjXuX0YrMTfnWUyCaIe/zeI1wqjNfN9XOk= github.com/larksuite/oapi-sdk-go/v3 v3.2.9 h1:9zQAGrzhibNwdaGRkWUP1cAd2k2dJJDpbSffcfK0wPw= github.com/larksuite/oapi-sdk-go/v3 v3.2.9/go.mod h1:ZEplY+kwuIrj/nqw5uSCINNATcH3KdxSN7y+UxYY5fI= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matoous/go-nanoid v1.5.0/go.mod h1:zyD2a71IubI24efhpvkJz+ZwfwagzgSO6UNiFsZKN7U= diff --git a/service/exceptionmonitor/helper/monitor/cockroachdb_monitor.go b/service/exceptionmonitor/helper/monitor/cockroachdb_monitor.go new file mode 100644 index 00000000000..c2a5ece3e6a --- /dev/null +++ b/service/exceptionmonitor/helper/monitor/cockroachdb_monitor.go @@ -0,0 +1,54 @@ +package monitor + +import ( + "fmt" + "log" + "time" + + "github.com/labring/sealos/service/exceptionmonitor/api" + "github.com/labring/sealos/service/exceptionmonitor/helper/notification" + "gorm.io/driver/postgres" + "gorm.io/gorm" + "gorm.io/gorm/logger" +) + +func CockroachMonitor() { + for api.CockroachMonitor { + notificationInfo := &api.Info{ + FeishuWebHook: api.FeishuWebhookURLMap["FeishuWebhookURLCockroachDB"], + } + monitorCockroachDB(api.GlobalCockroachURI, "Global", notificationInfo) + monitorCockroachDB(api.LocalCockroachURI, "Local", notificationInfo) + + time.Sleep(5 * time.Minute) + } +} + +func monitorCockroachDB(uri, label string, notificationInfo *api.Info) { + if err := checkCockroachDB(uri); err != nil { + message := notification.GetCockroachMessage(err.Error(), label) + if sendErr := notification.SendFeishuNotification(notificationInfo, message); sendErr != nil { + log.Printf("Failed to send Feishu notification for %s: %v", label, sendErr) + } + } +} + +func checkCockroachDB(CockroachConnection string) error { + db, err := gorm.Open(postgres.Open(CockroachConnection), &gorm.Config{ + Logger: logger.Discard, + }) + if err != nil { + return fmt.Errorf("failed to connect to CockroachDB: %v", err) + } + + sqlDB, err := db.DB() + if err != nil { + return fmt.Errorf("failed to get database instance: %v", err) + } + defer sqlDB.Close() + + if err := sqlDB.Ping(); err != nil { + return fmt.Errorf("failed to ping CockroachDB: %v", err) + } + return nil +} diff --git a/service/exceptionmonitor/helper/monitor/database_backup_monitor.go b/service/exceptionmonitor/helper/monitor/database_backup_monitor.go index c690a34a685..d5cce4f993d 100644 --- a/service/exceptionmonitor/helper/monitor/database_backup_monitor.go +++ b/service/exceptionmonitor/helper/monitor/database_backup_monitor.go @@ -90,17 +90,18 @@ func processBackup(backup unstructured.Unstructured) { } func SendBackupNotification(backupName, namespace, status, startTimestamp string) { - notificationInfo := notification.Info{ + notificationInfo := api.Info{ DatabaseClusterName: backupName, Namespace: namespace, - Status: status, + ExceptionStatus: status, ExceptionType: "备份", PerformanceType: "Backup", - NotificationType: "exception", + NotificationType: notification.ExceptionType, + FeishuWebHook: api.FeishuWebhookURLMap["FeishuWebhookURLBackup"], } if _, ok := api.LastBackupStatusMap[backupName]; !ok { - message := notification.GetBackupMessage("exception", namespace, backupName, status, startTimestamp, "") - if err := notification.SendFeishuNotification(notificationInfo, message, api.FeishuWebhookURLMap["FeishuWebhookURLBackup"]); err != nil { + message := notification.GetBackupMessage(notification.ExceptionType, namespace, backupName, status, startTimestamp, "") + if err := notification.SendFeishuNotification(¬ificationInfo, message); err != nil { log.Printf("Error sending exception notification:%v", err) } api.LastBackupStatusMap[backupName] = status diff --git a/service/exceptionmonitor/helper/monitor/database_monitor.go b/service/exceptionmonitor/helper/monitor/database_monitor.go index 59eb8ad5949..f1afb0383d6 100644 --- a/service/exceptionmonitor/helper/monitor/database_monitor.go +++ b/service/exceptionmonitor/helper/monitor/database_monitor.go @@ -7,10 +7,9 @@ import ( "strings" "time" - "k8s.io/apimachinery/pkg/api/errors" - "github.com/labring/sealos/service/exceptionmonitor/api" "github.com/labring/sealos/service/exceptionmonitor/helper/notification" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" @@ -33,6 +32,14 @@ var ( Version: "v1", Resource: "users", } + databasePodNameMap = map[string]string{ + "redis": "redis", + "kafka": "kafka-broker", + "apecloud-mysql": "mysql", + "postgresql": "postgresql", + "milvus": "milvus", + "mongodb": "mongodb", + } ) func DatabaseExceptionMonitor() { @@ -46,11 +53,20 @@ func DatabaseExceptionMonitor() { } func checkDeletedDatabases() { - for databaseClusterUID, namespaceAndDatabaseClusterName := range api.DatabaseNamespaceMap { - namespace, databaseClusterName := getNamespaceAndDatabaseClusterName(namespaceAndDatabaseClusterName) - cluster, err := api.DynamicClient.Resource(databaseClusterGVR).Namespace(namespace).Get(context.Background(), databaseClusterName, metav1.GetOptions{}) + //for databaseClusterUID, namespaceAndDatabaseClusterName := range api.DatabaseNamespaceMap { + for _, notificationInfo := range api.DatabaseNotificationInfoMap { + //namespace, databaseClusterName := getNamespaceAndDatabaseClusterName(namespaceAndDatabaseClusterName) + cluster, err := api.DynamicClient.Resource(databaseClusterGVR).Namespace(notificationInfo.Namespace).Get(context.Background(), notificationInfo.DatabaseClusterName, metav1.GetOptions{}) if cluster == nil && errors.IsNotFound(err) { - handleClusterRecovery(databaseClusterUID, databaseClusterName, "", "Deleted") + //notificationInfo := api.Info{ + // DatabaseClusterUID: databaseClusterUID, + // Namespace: notificationInfo.Namespace, + // DatabaseClusterName: databaseClusterName, + // RecoveryStatus: "Deleted", + //} + notificationInfo.RecoveryStatus = "Deleted" + notificationInfo.RecoveryTime = time.Now().Format("2006-01-02 15:04:05") + handleClusterRecovery(notificationInfo) } } } @@ -88,99 +104,107 @@ func checkDatabasesInNamespace(namespace string) error { } func processCluster(cluster metav1unstructured.Unstructured) { - databaseClusterName, databaseType, namespace, databaseClusterUID := cluster.GetName(), cluster.GetLabels()[api.DatabaseTypeLabel], cluster.GetNamespace(), string(cluster.GetUID()) - status, _, err := metav1unstructured.NestedString(cluster.Object, "status", "phase") - if err != nil { - log.Printf("Unable to get %s status in ns %s: %v", databaseClusterName, namespace, err) - } - switch status { + // todo 获取数据库信息抽成一个函数,封装在notificationInfo中 + notificationInfo := api.Info{} + getClusterDatabaseInfo(cluster, ¬ificationInfo) + switch notificationInfo.ExceptionStatus { case api.StatusRunning, api.StatusStopped: - handleClusterRecovery(databaseClusterUID, databaseClusterName, namespace, status) + if _, ok := api.DatabaseNotificationInfoMap[notificationInfo.DatabaseClusterUID]; ok { + recoveryNotificationInfo := api.DatabaseNotificationInfoMap[notificationInfo.DatabaseClusterUID] + recoveryNotificationInfo.RecoveryStatus, recoveryNotificationInfo.RecoveryTime = getClusterDatabaseStatus(cluster, recoveryNotificationInfo) + handleClusterRecovery(recoveryNotificationInfo) + } case api.StatusDeleting, api.StatusStopping: - // No action needed + // nothing to do break case api.StatusUnknown: - if _, ok := api.LastDatabaseClusterStatus[databaseClusterUID]; !ok { - api.LastDatabaseClusterStatus[databaseClusterUID] = status - api.DatabaseNamespaceMap[databaseClusterUID] = namespace + "-" + databaseClusterName - api.ExceptionDatabaseMap[databaseClusterUID] = true - alertMessage, feishuWebHook, notification := prepareAlertMessage(databaseClusterUID, databaseClusterName, namespace, status, "", "status is empty", 0) - if err := sendAlert(alertMessage, feishuWebHook, databaseClusterUID, notification); err != nil { - log.Printf("Failed to send feishu %s in ns %s: %v", databaseClusterName, namespace, err) + //一般都是在新建,应该发到新建的飞书群中 + if _, ok := api.DatabaseNotificationInfoMap[notificationInfo.DatabaseClusterUID]; !ok { + api.DatabaseNotificationInfoMap[notificationInfo.DatabaseClusterUID] = ¬ificationInfo + //api.LastDatabaseClusterStatus[notificationInfo.DatabaseClusterUID] = notificationInfo.ExceptionStatus + //api.DatabaseNamespaceMap[notificationInfo.DatabaseClusterUID] = notificationInfo.Namespace + "-" + notificationInfo.DatabaseClusterName + //api.ExceptionDatabaseMap[notificationInfo.DatabaseClusterUID] = true + notificationInfo.Events = "status is empty" + notificationInfo.DebtLevel = "" + alertMessage := prepareAlertMessage(¬ificationInfo, 0) + if err := sendAlert(alertMessage, ¬ificationInfo); err != nil { + log.Printf("Failed to send feishu %s in ns %s: %v", notificationInfo.DatabaseClusterName, notificationInfo.Namespace, err) } } default: - handleClusterException(databaseClusterUID, databaseClusterName, namespace, databaseType, status) + //Updating、Creating、Failed、Abnormal + //notificationInfo.DatabaseClusterUID, databaseClusterName, namespace, databaseType, status + handleClusterException(¬ificationInfo) } } -func handleClusterRecovery(databaseClusterUID, databaseClusterName, namespace, status string) { - if api.ExceptionDatabaseMap[databaseClusterUID] { - notificationInfo := notification.Info{ - DatabaseClusterName: databaseClusterName, - Namespace: namespace, - Status: status, - ExceptionType: "状态", - NotificationType: "recovery", - } - recoveryMessage := notification.GetNotificationMessage(notificationInfo) - if err := notification.SendFeishuNotification(notificationInfo, recoveryMessage, api.FeishuWebHookMap[databaseClusterUID]); err != nil { - log.Printf("Error sending recovery notification: %v", err) - } - cleanClusterStatus(databaseClusterUID) +func handleClusterRecovery(notificationInfo *api.Info) { + //if api.ExceptionDatabaseMap[notificationInfo.DatabaseClusterUID] { + notificationInfo.NotificationType = "recovery" + recoveryMessage := notification.GetNotificationMessage(notificationInfo) + //getClusterDatabaseStatus应该在上层去做,因为有可能是已经删的数据状态更新信息,在这里获取的话,就没法拿到状态信息 + //notificationInfo.RecoveryStatus, notificationInfo.RecoveryStatusTime = getClusterDatabaseStatus(cluster, notificationInfo) + if err := notification.SendFeishuNotification(notificationInfo, recoveryMessage); err != nil { + log.Printf("Error sending recovery notification: %v", err) } + cleanClusterStatus(notificationInfo.DatabaseClusterUID) } func cleanClusterStatus(databaseClusterUID string) { - delete(api.LastDatabaseClusterStatus, databaseClusterUID) + delete(api.DatabaseNotificationInfoMap, databaseClusterUID) delete(api.DiskFullNamespaceMap, databaseClusterUID) - delete(api.FeishuWebHookMap, databaseClusterUID) - delete(api.ExceptionDatabaseMap, databaseClusterUID) - delete(api.DatabaseNamespaceMap, databaseClusterUID) + //delete(api.FeishuWebHookMap, databaseClusterUID) + //delete(api.ExceptionDatabaseMap, databaseClusterUID) + //delete(api.DatabaseNamespaceMap, databaseClusterUID) } -func handleClusterException(databaseClusterUID, databaseClusterName, namespace, databaseType, status string) { - if _, ok := api.LastDatabaseClusterStatus[databaseClusterUID]; !ok && !api.DebtNamespaceMap[namespace] { - api.LastDatabaseClusterStatus[databaseClusterUID] = status - api.DatabaseNamespaceMap[databaseClusterUID] = namespace + "-" + databaseClusterName - api.ExceptionDatabaseMap[databaseClusterUID] = true - if err := processClusterException(databaseClusterUID, databaseClusterName, namespace, databaseType, status); err != nil { - log.Printf("Failed to process cluster %s exception in ns %s: %v", databaseClusterName, namespace, err) +func handleClusterException(notificationInfo *api.Info) { + if _, ok := api.DatabaseNotificationInfoMap[notificationInfo.DatabaseClusterUID]; !ok && !api.DebtNamespaceMap[notificationInfo.Namespace] { + api.DatabaseNotificationInfoMap[notificationInfo.DatabaseClusterUID] = notificationInfo + //api.LastDatabaseClusterStatus[notificationInfo.DatabaseClusterUID] = notificationInfo.ExceptionStatus + //api.DatabaseNamespaceMap[notificationInfo.DatabaseClusterUID] = notificationInfo.Namespace + "-" + notificationInfo.DatabaseClusterName + //api.ExceptionDatabaseMap[notificationInfo.DatabaseClusterUID] = true + //notificationInfo.DatabaseClusterUID, databaseClusterName, namespace, databaseType, status + if err := processClusterException(notificationInfo); err != nil { + log.Printf("Failed to process cluster %s exception in ns %s: %v", notificationInfo.DatabaseClusterName, notificationInfo.Namespace, err) } } - //if !api.DebtNamespaceMap[namespace] && !api.ExceptionDatabaseMap[databaseClusterName] { - // - //} } -func processClusterException(databaseClusterUID, databaseClusterName, namespace, databaseType, status string) error { - debt, debtLevel, _ := checkDebt(namespace) +func processClusterException(notificationInfo *api.Info) error { + debt, debtLevel, _ := checkDebt(notificationInfo.Namespace) + notificationInfo.DebtLevel = debtLevel if debt { - databaseEvents, send := getDatabaseClusterEvents(databaseClusterName, namespace) + //databaseClusterName, namespace + databaseEvents, send := getDatabaseClusterEvents(notificationInfo) if send { - maxUsage, err := checkPerformance(namespace, databaseClusterName, databaseType, "disk") + //namespace, databaseClusterName, databaseType + maxUsage, err := checkPerformance(notificationInfo, "disk") if err != nil { return err } - alertMessage, feishuWebHook, notification := prepareAlertMessage(databaseClusterUID, databaseClusterName, namespace, status, debtLevel, databaseEvents, maxUsage) - if err := sendAlert(alertMessage, feishuWebHook, databaseClusterUID, notification); err != nil { + notificationInfo.Events = databaseEvents + //notificationInfo.DatabaseClusterUID, databaseClusterName, namespace, status, debtLevel, databaseEvents + alertMessage := prepareAlertMessage(notificationInfo, maxUsage) + if err := sendAlert(alertMessage, notificationInfo); err != nil { return err } } else { - if err := notifyQuotaExceeded(databaseClusterName, namespace, status, debtLevel); err != nil { + //databaseClusterName, namespace, status, debtLevel + if err := notifyQuotaExceeded(notificationInfo); err != nil { return err } } } else { - api.DebtNamespaceMap[namespace] = true - delete(api.LastDatabaseClusterStatus, databaseClusterUID) + api.DebtNamespaceMap[notificationInfo.Namespace] = true + delete(api.DatabaseNotificationInfoMap, notificationInfo.DatabaseClusterUID) } return nil } -func getDatabaseClusterEvents(databaseClusterName, namespace string) (string, bool) { - events, err := api.ClientSet.CoreV1().Events(namespace).List(context.TODO(), metav1.ListOptions{ - FieldSelector: fmt.Sprintf("involvedObject.name=%s", databaseClusterName), +func getDatabaseClusterEvents(notificationInfo *api.Info) (string, bool) { + events, err := api.ClientSet.CoreV1().Events(notificationInfo.Namespace).List(context.TODO(), metav1.ListOptions{ + FieldSelector: fmt.Sprintf("involvedObject.name=%s", notificationInfo.DatabaseClusterName), }) if err != nil { fmt.Printf("Failed get events from databaseCluster: %v\n", err) @@ -198,61 +222,66 @@ func databaseQuotaExceptionFilter(databaseEvents string) bool { return !strings.Contains(databaseEvents, api.ExceededQuotaException) } -func prepareAlertMessage(databaseClusterUID, databaseClusterName, namespace, status, debtLevel, databaseEvents string, maxUsage float64) (string, string, notification.Info) { - alertMessage, feishuWebHook := "", "" - notificationInfo := notification.Info{ - DatabaseClusterName: databaseClusterName, - Namespace: namespace, - Status: status, - DebtLevel: debtLevel, - ExceptionType: "状态", - Events: databaseEvents, - NotificationType: "exception", - } +func prepareAlertMessage(notificationInfo *api.Info, maxUsage float64) string { + alertMessage := "" + notificationInfo.ExceptionType = "状态" + notificationInfo.NotificationType = notification.ExceptionType if maxUsage < api.DatabaseExceptionMonitorThreshold { //status == "Creating" || status == "Deleting" || status == "Stopping" - if status == "Creating" { - feishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLCSD"] + if notificationInfo.ExceptionStatus == "Creating" { + notificationInfo.FeishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLCSD"] } else { - feishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLUFA"] + notificationInfo.FeishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLUFA"] } alertMessage = notification.GetNotificationMessage(notificationInfo) } else { - if !api.DiskFullNamespaceMap[databaseClusterUID] { - feishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLOther"] + if !api.DiskFullNamespaceMap[notificationInfo.DatabaseClusterUID] { + notificationInfo.FeishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLOther"] notificationInfo.Reason = "disk is full" alertMessage = notification.GetNotificationMessage(notificationInfo) - notification.CreateNotification(namespace, databaseClusterName, status, "disk is full", "磁盘满了") + //namespace, databaseClusterName, status + notification.CreateNotification(notificationInfo, "disk is full", "磁盘满了") } - api.DiskFullNamespaceMap[databaseClusterUID] = true + api.DiskFullNamespaceMap[notificationInfo.DatabaseClusterUID] = true } - return alertMessage, feishuWebHook, notificationInfo + return alertMessage } -func sendAlert(alertMessage, feishuWebHook, databaseClusterUID string, notificationInfo notification.Info) error { - api.FeishuWebHookMap[databaseClusterUID] = feishuWebHook - return notification.SendFeishuNotification(notificationInfo, alertMessage, feishuWebHook) +func sendAlert(alertMessage string, notificationInfo *api.Info) error { + //api.FeishuWebHookMap[notificationInfo.DatabaseClusterUID] = feishuWebHook + return notification.SendFeishuNotification(notificationInfo, alertMessage) } -func notifyQuotaExceeded(databaseClusterName, namespace, status, debtLevel string) error { - notificationInfo := notification.Info{ - DatabaseClusterName: databaseClusterName, - Namespace: namespace, - Status: status, - DebtLevel: debtLevel, - Reason: api.ExceededQuotaException, - ExceptionType: "状态", - NotificationType: "exception", - } +func notifyQuotaExceeded(notificationInfo *api.Info) error { + notificationInfo.ExceptionType = "状态" + notificationInfo.Reason = api.ExceededQuotaException + notificationInfo.NotificationType = notification.ExceptionType + notificationInfo.FeishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLOther"] alertMessage := notification.GetNotificationMessage(notificationInfo) - notification.CreateNotification(namespace, databaseClusterName, status, api.ExceededQuotaException, "Quato满了") - return notification.SendFeishuNotification(notificationInfo, alertMessage, api.FeishuWebhookURLMap["FeishuWebhookURLOther"]) + notification.CreateNotification(notificationInfo, api.ExceededQuotaException, "Quato满了") + return notification.SendFeishuNotification(notificationInfo, alertMessage) +} + +func getClusterDatabaseInfo(cluster metav1unstructured.Unstructured, notificationInfo *api.Info) { + databaseClusterName, databaseType, namespace, databaseClusterUID := cluster.GetName(), cluster.GetLabels()[api.DatabaseTypeLabel], cluster.GetNamespace(), string(cluster.GetUID()) + notificationInfo.DatabaseType = databaseType + notificationInfo.Namespace = namespace + notificationInfo.DatabaseClusterName = databaseClusterName + notificationInfo.DatabaseClusterUID = databaseClusterUID + notificationInfo.ExceptionStatus, notificationInfo.ExceptionStatusTime = getClusterDatabaseStatus(cluster, notificationInfo) } -func getNamespaceAndDatabaseClusterName(namespaceAndDatabaseClusterName string) (string, string) { - firstIndex := strings.Index(namespaceAndDatabaseClusterName, "-") - secondIndex := strings.Index(namespaceAndDatabaseClusterName[firstIndex+1:], "-") + firstIndex + 1 - namespace := namespaceAndDatabaseClusterName[:secondIndex] - databaseClusterName := namespaceAndDatabaseClusterName[secondIndex+1:] - return namespace, databaseClusterName +func getClusterDatabaseStatus(cluster metav1unstructured.Unstructured, notificationInfo *api.Info) (string, string) { + status, _, _ := metav1unstructured.NestedString(cluster.Object, "status", "phase") + + databaseClusterStatus, _, _ := metav1unstructured.NestedMap(cluster.Object, "status") + + podName := databasePodNameMap[notificationInfo.DatabaseType] + podsReadyTime, _, _ := metav1unstructured.NestedString(databaseClusterStatus, "components", podName, "podsReadyTime") + + parsedTime, _ := time.Parse(time.RFC3339, podsReadyTime) + adjustedTime := parsedTime.Add(8 * time.Hour) + + formattedTime := adjustedTime.Format("2006-01-02 15:04:05") + return status, formattedTime } diff --git a/service/exceptionmonitor/helper/monitor/database_performance_monitor.go b/service/exceptionmonitor/helper/monitor/database_performance_monitor.go index 25523538d75..ee559f33114 100644 --- a/service/exceptionmonitor/helper/monitor/database_performance_monitor.go +++ b/service/exceptionmonitor/helper/monitor/database_performance_monitor.go @@ -56,91 +56,91 @@ func checkDatabasePerformanceInNamespace(namespace string) error { } func monitorCluster(cluster unstructured.Unstructured) { - databaseClusterName, databaseType, namespace, UID := cluster.GetName(), cluster.GetLabels()[api.DatabaseTypeLabel], cluster.GetNamespace(), string(cluster.GetUID()) - status, found, err := unstructured.NestedString(cluster.Object, "status", "phase") - if err != nil || !found { - log.Printf("Unable to get %s status in ns %s: %v", databaseClusterName, namespace, err) - } - debt, _, _ := checkDebt(namespace) + notificationInfo := api.Info{} + getClusterDatabaseInfo(cluster, ¬ificationInfo) + //notificationInfo.DatabaseClusterName, notificationInfo.DatabaseType, notificationInfo.Namespace, notificationInfo.DatabaseClusterUID = cluster.GetName(), cluster.GetLabels()[api.DatabaseTypeLabel], cluster.GetNamespace(), string(cluster.GetUID()) + //status, found, err := unstructured.NestedString(cluster.Object, "status", "phase") + //if err != nil || !found { + // log.Printf("Unable to get %s status in ns %s: %v", notificationInfo.DatabaseClusterName, notificationInfo.Namespace, err) + //} + debt, _, _ := checkDebt(notificationInfo.Namespace) if !debt { return } - info := notification.Info{ - DatabaseClusterName: databaseClusterName, - Namespace: namespace, - Status: status, - NotificationType: "exception", - ExceptionType: "阀值", - } - switch status { + notificationInfo.NotificationType = notification.ExceptionType + notificationInfo.ExceptionType = "阀值" + switch notificationInfo.ExceptionStatus { case api.StatusDeleting, api.StatusCreating, api.StatusStopping, api.StatusStopped, api.StatusUnknown: break default: if api.CPUMemMonitor { - handleCPUMemMonitor(namespace, databaseClusterName, databaseType, UID, info) + handleCPUMemMonitor(¬ificationInfo) } if api.DiskMonitor { - handleDiskMonitor(namespace, databaseClusterName, databaseType, UID, info) + handleDiskMonitor(¬ificationInfo) } } } -func handleCPUMemMonitor(namespace, databaseClusterName, databaseType, UID string, info notification.Info) { - if cpuUsage, err := CPUMemMonitor(namespace, databaseClusterName, databaseType, "cpu"); err == nil { - processUsage(cpuUsage, api.DatabaseCPUMonitorThreshold, "CPU", UID, info, api.CPUMonitorNamespaceMap) +func handleCPUMemMonitor(notificationInfo *api.Info) { + if cpuUsage, err := CPUMemMonitor(notificationInfo, "cpu"); err == nil { + processUsage(cpuUsage, api.DatabaseCPUMonitorThreshold, "CPU", notificationInfo, api.CPUMonitorNamespaceMap) } else { log.Printf("Failed to monitor CPU: %v", err) } - if memUsage, err := CPUMemMonitor(namespace, databaseClusterName, databaseType, "memory"); err == nil { - processUsage(memUsage, api.DatabaseMemMonitorThreshold, "内存", UID, info, api.MemMonitorNamespaceMap) + if memUsage, err := CPUMemMonitor(notificationInfo, "memory"); err == nil { + processUsage(memUsage, api.DatabaseMemMonitorThreshold, "内存", notificationInfo, api.MemMonitorNamespaceMap) } else { log.Printf("Failed to monitor Memory: %v", err) } } -func handleDiskMonitor(namespace, databaseClusterName, databaseType, UID string, info notification.Info) { - if maxUsage, err := checkPerformance(namespace, databaseClusterName, databaseType, "disk"); err == nil { - processUsage(maxUsage, api.DatabaseDiskMonitorThreshold, "磁盘", UID, info, api.DiskMonitorNamespaceMap) +func handleDiskMonitor(notificationInfo *api.Info) { + if maxUsage, err := checkPerformance(notificationInfo, "disk"); err == nil { + processUsage(maxUsage, api.DatabaseDiskMonitorThreshold, "磁盘", notificationInfo, api.DiskMonitorNamespaceMap) } else { log.Printf("Failed to monitor Disk: %v", err) } } -func processUsage(usage float64, threshold float64, performanceType, UID string, info notification.Info, monitorMap map[string]bool) { - info.PerformanceType = performanceType +func processUsage(usage float64, threshold float64, performanceType string, notificationInfo *api.Info, monitorMap map[string]bool) { + notificationInfo.PerformanceType = performanceType usageStr := strconv.FormatFloat(usage, 'f', 2, 64) if performanceType == "CPU" { - info.CPUUsage = usageStr + notificationInfo.CPUUsage = usageStr } else if performanceType == "内存" { - info.MemUsage = usageStr + notificationInfo.MemUsage = usageStr } else if performanceType == "磁盘" { - info.DiskUsage = usageStr + notificationInfo.DiskUsage = usageStr } - if usage >= threshold && !monitorMap[UID] { - alertMessage := notification.GetNotificationMessage(info) - if err := notification.SendFeishuNotification(info, alertMessage, api.FeishuWebhookURLMap["FeishuWebhookURLImportant"]); err != nil { + if usage >= threshold && !monitorMap[notificationInfo.DatabaseClusterUID] { + alertMessage := notification.GetNotificationMessage(notificationInfo) + notificationInfo.FeishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLImportant"] + if err := notification.SendFeishuNotification(notificationInfo, alertMessage); err != nil { log.Printf("Failed to send notification: %v", err) } - monitorMap[UID] = true + monitorMap[notificationInfo.DatabaseClusterUID] = true if performanceType != "磁盘" { return } ZNThreshold := NumberToChinese(int(threshold)) - if err := notification.SendToSms(info.Namespace, info.DatabaseClusterName, api.ClusterName, "数据库"+performanceType+"超过百分之"+ZNThreshold); err != nil { + if err := notification.SendToSms(notificationInfo, api.ClusterName, "数据库"+performanceType+"超过百分之"+ZNThreshold); err != nil { log.Printf("Failed to send Sms: %v", err) } - } else if usage < threshold && monitorMap[UID] { - info.NotificationType = "recovery" - alertMessage := notification.GetNotificationMessage(info) - if err := notification.SendFeishuNotification(info, alertMessage, api.FeishuWebhookURLMap["FeishuWebhookURLImportant"]); err != nil { + } else if usage < threshold && monitorMap[notificationInfo.DatabaseClusterUID] { + notificationInfo.NotificationType = "recovery" + notificationInfo.RecoveryTime = time.Now().Add(8 * time.Hour).Format("2006-01-02 15:04:05") + alertMessage := notification.GetNotificationMessage(notificationInfo) + notificationInfo.FeishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLImportant"] + if err := notification.SendFeishuNotification(notificationInfo, alertMessage); err != nil { log.Printf("Failed to send notification: %v", err) } - delete(monitorMap, UID) + delete(monitorMap, notificationInfo.DatabaseClusterUID) } } -func CPUMemMonitor(namespace, databaseClusterName, databaseType, checkType string) (float64, error) { - return checkPerformance(namespace, databaseClusterName, databaseType, checkType) +func CPUMemMonitor(notificationInfo *api.Info, checkType string) (float64, error) { + return checkPerformance(notificationInfo, checkType) } func NumberToChinese(num int) string { diff --git a/service/exceptionmonitor/helper/monitor/performance.go b/service/exceptionmonitor/helper/monitor/performance.go index db3b993da71..d7cff33dac1 100644 --- a/service/exceptionmonitor/helper/monitor/performance.go +++ b/service/exceptionmonitor/helper/monitor/performance.go @@ -15,11 +15,11 @@ import ( "github.com/labring/sealos/service/exceptionmonitor/api" ) -func checkPerformance(namespace, databaseClusterName, databaseType, checkType string) (float64, error) { +func checkPerformance(notificationInfo *api.Info, checkType string) (float64, error) { params := url.Values{} - params.Add("namespace", namespace) - params.Add("app", databaseClusterName) - params.Add("type", databaseType) + params.Add("namespace", notificationInfo.Namespace) + params.Add("app", notificationInfo.DatabaseClusterName) + params.Add("type", notificationInfo.DatabaseType) params.Add("query", checkType) urlStr := api.BaseURL + "?" + params.Encode() @@ -29,7 +29,7 @@ func checkPerformance(namespace, databaseClusterName, databaseType, checkType st return 0.0, err } - kubeconfig, err := getKubeConfig(namespace) + kubeconfig, err := getKubeConfig(notificationInfo.Namespace) if err != nil { return 0.0, err } diff --git a/service/exceptionmonitor/helper/monitor/quota_monitor.go b/service/exceptionmonitor/helper/monitor/quota_monitor.go index 87a201381ff..44edd310d46 100644 --- a/service/exceptionmonitor/helper/monitor/quota_monitor.go +++ b/service/exceptionmonitor/helper/monitor/quota_monitor.go @@ -39,18 +39,19 @@ func checkQuota() error { if len(quotaList.Items) != 1 || quotaList.Items[0].Name != "quota-"+ns.Name { continue } - nsQuota := notification.NameSpaceQuota{ + nsQuota := api.NameSpaceQuota{ NameSpace: ns.Name, } - notificationInfo := notification.Info{ + notificationInfo := api.Info{ ExceptionType: "Quota", PerformanceType: "Quota", - NotificationType: "exception", + NotificationType: notification.ExceptionType, } send := processQuota(quotaList, &nsQuota) if send { message := notification.GetQuotaMessage(&nsQuota) - if err := notification.SendFeishuNotification(notificationInfo, message, api.FeishuWebhookURLMap["FeishuWebhookURLQuota"]); err != nil { + notificationInfo.FeishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLQuota"] + if err := notification.SendFeishuNotification(¬ificationInfo, message); err != nil { log.Printf("Error sending exception notification:%v", err) } } @@ -58,7 +59,7 @@ func checkQuota() error { return nil } -func processQuota(quotaList *v1.ResourceQuotaList, nsQuota *notification.NameSpaceQuota) bool { +func processQuota(quotaList *v1.ResourceQuotaList, nsQuota *api.NameSpaceQuota) bool { send := false for resourceName, hardQuantity := range quotaList.Items[0].Status.Hard { usedQuantity, exists := quotaList.Items[0].Status.Used[resourceName] diff --git a/service/exceptionmonitor/helper/notification/desktop.go b/service/exceptionmonitor/helper/notification/desktop.go index bc2c626c4d9..5d3908b1c11 100644 --- a/service/exceptionmonitor/helper/notification/desktop.go +++ b/service/exceptionmonitor/helper/notification/desktop.go @@ -31,7 +31,7 @@ func randString(n int) (string, error) { return string(b), nil } -func CreateNotification(namespace, name, status, notificationMessage, zhNotificationMessage string) { +func CreateNotification(notificationInfo *api.Info, notificationMessage, zhNotificationMessage string) { gvr := schema.GroupVersionResource{ Group: "notification.sealos.io", Version: "v1", @@ -40,14 +40,14 @@ func CreateNotification(namespace, name, status, notificationMessage, zhNotifica randomSuffix, _ := randString(5) now := time.Now().UTC().Unix() - message := fmt.Sprintf("Because %s , Database %s current status : %s , Please check in time.", notificationMessage, name, status) - zhMessage := fmt.Sprintf("因为 %s , 数据库 %s 当前状态 : %s , 请及时检查.", zhNotificationMessage, name, status) + message := fmt.Sprintf("Because %s , Database %s current status : %s , Please check in time.", notificationMessage, notificationInfo.DatabaseClusterName, notificationInfo.ExceptionStatus) + zhMessage := fmt.Sprintf("因为 %s , 数据库 %s 当前状态 : %s , 请及时检查.", zhNotificationMessage, notificationInfo.DatabaseClusterName, notificationInfo.ExceptionStatus) notification := &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "notification.sealos.io/v1", "kind": "Notification", "metadata": map[string]interface{}{ - "name": "database-exception" + name + randomSuffix, + "name": "database-exception" + notificationInfo.DatabaseClusterName + randomSuffix, }, "spec": map[string]interface{}{ "title": "Database Exception", @@ -67,7 +67,7 @@ func CreateNotification(namespace, name, status, notificationMessage, zhNotifica }, } - _, err := api.DynamicClient.Resource(gvr).Namespace(namespace).Create(context.TODO(), notification, metav1.CreateOptions{}) + _, err := api.DynamicClient.Resource(gvr).Namespace(notificationInfo.Namespace).Create(context.TODO(), notification, metav1.CreateOptions{}) if err != nil { log.Printf("Failed to send desktop notification: %v", err) } diff --git a/service/exceptionmonitor/helper/notification/feishu.go b/service/exceptionmonitor/helper/notification/feishu.go index 312547f9866..796d1bdbcd2 100644 --- a/service/exceptionmonitor/helper/notification/feishu.go +++ b/service/exceptionmonitor/helper/notification/feishu.go @@ -6,7 +6,6 @@ import ( "fmt" "log" "regexp" - "time" "github.com/labring/sealos/service/exceptionmonitor/api" lark "github.com/larksuite/oapi-sdk-go/v3" @@ -20,44 +19,59 @@ var ( feiShuClient *lark.Client ) -type Info struct { - DatabaseClusterName string - Namespace string - Status string - DebtLevel string - Events string - Reason string - NotificationType string - DiskUsage string - CPUUsage string - MemUsage string - PerformanceType string - ExceptionType string +func InitFeishuClient() { + feiShuClient = lark.NewClient(api.APPID, api.APPSECRET) } -type NameSpaceQuota struct { - NameSpace string - CPULimit string - MemLimit string - GPULimit string - EphemeralStorageLimit string - ObjectStorageLimit string - NodePortLimit string - StorageLimit string - CPUUsage string - MemUsage string - GPUUsage string - EphemeralStorageUsage string - ObjectStorageUsage string - NodePortUsage string - StorageUsage string -} +func GetCockroachMessage(errMessage, cockroachType string) string { + headerTemplate := "red" + titleContent := "小强数据库异常告警" + elements := []map[string]interface{}{ + { + "tag": "div", + "text": map[string]string{ + "content": fmt.Sprintf("集群环境:%s", api.ClusterName), + "tag": "lark_md", + }, + }, + { + "tag": "div", + "text": map[string]string{ + "content": fmt.Sprintf("数据库类型:%s", cockroachType), + "tag": "lark_md", + }, + }, + { + "tag": "div", + "text": map[string]string{ + "content": fmt.Sprintf("异常信息:%s", errMessage), + "tag": "lark_md", + }, + }, + } + card := map[string]interface{}{ + "config": map[string]bool{ + "wide_screen_mode": true, + }, + "elements": elements, + "header": map[string]interface{}{ + "template": headerTemplate, + "title": map[string]string{ + "content": titleContent, + "tag": "plain_text", + }, + }, + } -func InitFeishuClient() { - feiShuClient = lark.NewClient(api.APPID, api.APPSECRET) + databaseMessage, err := json.Marshal(card) + if err != nil { + fmt.Println("Error marshaling JSON:", err) + return "" + } + return string(databaseMessage) } -func GetNotificationMessage(notificationInfo Info) string { +func GetNotificationMessage(notificationInfo *api.Info) string { headerTemplate := "red" titleContent := "数据库" + notificationInfo.ExceptionType + "告警" usage := "" @@ -68,8 +82,8 @@ func GetNotificationMessage(notificationInfo Info) string { } else if notificationInfo.PerformanceType == "磁盘" { usage = notificationInfo.DiskUsage } - var elements []map[string]interface{} + //公共部分,状态和阀值的异常、恢复过程都需要,需要判断是否首次发送信息,是的话,就用这里,不是的话,就跳过(在之前的内容上追加) commonElements := []map[string]interface{}{ { "tag": "div", @@ -95,7 +109,7 @@ func GetNotificationMessage(notificationInfo Info) string { { "tag": "div", "text": map[string]string{ - "content": fmt.Sprintf("数据库状态:%s", notificationInfo.Status), + "content": fmt.Sprintf("数据库状态:%s", notificationInfo.ExceptionStatus), "tag": "lark_md", }, }, @@ -103,7 +117,14 @@ func GetNotificationMessage(notificationInfo Info) string { if notificationInfo.NotificationType == ExceptionType && notificationInfo.ExceptionType == "状态" { exceptionElements := []map[string]interface{}{ + //这个异常时间需要给值 { + "tag": "div", + "text": map[string]string{ + "content": fmt.Sprintf("数据库异常时间:%s", notificationInfo.ExceptionStatusTime), + "tag": "lark_md", + }, + }, { "tag": "div", "text": map[string]string{ "content": fmt.Sprintf("欠费级别:%s", notificationInfo.DebtLevel), @@ -125,7 +146,7 @@ func GetNotificationMessage(notificationInfo Info) string { }, }, } - elements = append(commonElements, exceptionElements...) + notificationInfo.FeishuInfo = append(commonElements, exceptionElements...) } else if notificationInfo.ExceptionType == "阀值" { exceptionElements := []map[string]interface{}{ { @@ -136,16 +157,29 @@ func GetNotificationMessage(notificationInfo Info) string { }, }, } - elements = append(commonElements, exceptionElements...) + notificationInfo.FeishuInfo = append(commonElements, exceptionElements...) } if notificationInfo.NotificationType == "recovery" { + // todo 拿到之前的发送信息并加上,已做状态监控,未做阀值监控 headerTemplate = "blue" titleContent = "数据库" + notificationInfo.ExceptionType + "恢复通知" - elements = commonElements + //获取之前发送的飞书内容 + separatorElements := []map[string]interface{}{ + { + "tag": "div", + "text": map[string]string{ + "content": "-------------------------------------------", + "tag": "lark_md", + }, + }, + } + notificationInfo.FeishuInfo = append(notificationInfo.FeishuInfo, separatorElements...) + //elements = commonElements if notificationInfo.ExceptionType == "阀值" { - exceptionElements := []map[string]interface{}{ + //todo 数据库阀值的恢复时间怎么跟其它统一起来,需要在数据库阀值恢复中增加恢复时间 + usageRecoveryElements := []map[string]interface{}{ { "tag": "div", "text": map[string]string{ @@ -154,24 +188,32 @@ func GetNotificationMessage(notificationInfo Info) string { }, }, } - elements = append(elements, exceptionElements...) + notificationInfo.FeishuInfo = append(notificationInfo.FeishuInfo, usageRecoveryElements...) } - exceptionElements := []map[string]interface{}{ + recoveryTimeElements := []map[string]interface{}{ + { + "tag": "div", + "text": map[string]string{ + "content": fmt.Sprintf("数据库状态:%s", notificationInfo.RecoveryStatus), + "tag": "lark_md", + }, + }, { "tag": "div", "text": map[string]string{ - "content": fmt.Sprintf("数据库恢复时间:%s", time.Now().Add(8*time.Hour).Format("2006-01-02 15:04:05")), + "content": fmt.Sprintf("数据库恢复时间:%s", notificationInfo.RecoveryTime), "tag": "lark_md", }, }, } - elements = append(elements, exceptionElements...) + notificationInfo.FeishuInfo = append(notificationInfo.FeishuInfo, recoveryTimeElements...) } card := map[string]interface{}{ "config": map[string]bool{ "wide_screen_mode": true, }, - "elements": elements, + //elements替换成notificationInfo.FeishuInfo + "elements": notificationInfo.FeishuInfo, "header": map[string]interface{}{ "template": headerTemplate, "title": map[string]string{ @@ -189,9 +231,9 @@ func GetNotificationMessage(notificationInfo Info) string { return string(databaseMessage) } -func SendFeishuNotification(notification Info, message, feishuWebHook string) error { +func SendFeishuNotification(notification *api.Info, message string) error { if api.MonitorType != "all" { - feishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLImportant"] + notification.FeishuWebHook = api.FeishuWebhookURLMap["FeishuWebhookURLImportant"] } messageIDMap := getMessageIDMap(notification.PerformanceType) @@ -202,7 +244,7 @@ func SendFeishuNotification(notification Info, message, feishuWebHook string) er } delete(messageIDMap, notification.DatabaseClusterName) } else { - if err := createFeishuNotification(notification, message, feishuWebHook, messageIDMap); err != nil { + if err := createFeishuNotification(notification, message, messageIDMap); err != nil { return err } } @@ -246,11 +288,11 @@ func updateFeishuNotification(messageID, message string) error { return nil } -func createFeishuNotification(notification Info, message, feishuWebHook string, messageIDMap map[string]string) error { +func createFeishuNotification(notification *api.Info, message string, messageIDMap map[string]string) error { req := larkim.NewCreateMessageReqBuilder(). ReceiveIdType("chat_id"). Body(larkim.NewCreateMessageReqBodyBuilder(). - ReceiveId(feishuWebHook). + ReceiveId(notification.FeishuWebHook). MsgType("interactive"). Content(message).Build()).Build() @@ -317,7 +359,7 @@ func createCard(headerTemplate, headerTitle string, elements []map[string]string return card } -func GetQuotaMessage(nsQuota *NameSpaceQuota) string { +func GetQuotaMessage(nsQuota *api.NameSpaceQuota) string { var card map[string]interface{} elements := createQuotaElements(nsQuota) card = createCard("red", "Quota阀值通知", elements) @@ -330,7 +372,7 @@ func GetQuotaMessage(nsQuota *NameSpaceQuota) string { return databaseMessage } -func createQuotaElements(nsQuota *NameSpaceQuota) []map[string]string { +func createQuotaElements(nsQuota *api.NameSpaceQuota) []map[string]string { elements := []map[string]string{ {"label": "集群环境", "value": api.ClusterName}, {"label": "命名空间", "value": nsQuota.NameSpace}, @@ -339,7 +381,7 @@ func createQuotaElements(nsQuota *NameSpaceQuota) []map[string]string { return elements } -func addNonEmptyFieldsToElements(nsQuota *NameSpaceQuota, elements *[]map[string]string) { +func addNonEmptyFieldsToElements(nsQuota *api.NameSpaceQuota, elements *[]map[string]string) { fields := map[string]string{ "CPULimit": "CPU总量", "CPUUsage": "CPU使用率", diff --git a/service/exceptionmonitor/helper/notification/sms.go b/service/exceptionmonitor/helper/notification/sms.go index 5a50a3ceaef..ac1bd58c218 100644 --- a/service/exceptionmonitor/helper/notification/sms.go +++ b/service/exceptionmonitor/helper/notification/sms.go @@ -37,13 +37,13 @@ func GetPhoneNumberByNS(owner string) (string, error) { return phone, nil } -func SendToSms(namespace, databaseName, clusterName, content string) error { +func SendToSms(notificationInfo *api.Info, clusterName, content string) error { smsClient, err := utils.CreateSMSClient(os.Getenv("SMSAccessKeyID"), os.Getenv("SMSAccessKeySecret"), os.Getenv("SMSEndpoint")) if err != nil { return err } - name := strings.ReplaceAll(databaseName, "-", "/") - owner, _ := GetNSOwner(namespace) + name := strings.ReplaceAll(notificationInfo.DatabaseClusterName, "-", "/") + owner, _ := GetNSOwner(notificationInfo.Namespace) phoneNumbers, err := GetPhoneNumberByNS(owner) if err != nil { return err diff --git a/service/exceptionmonitor/main.go b/service/exceptionmonitor/main.go index fe518bc0006..209887d687f 100644 --- a/service/exceptionmonitor/main.go +++ b/service/exceptionmonitor/main.go @@ -19,6 +19,7 @@ func main() { go monitor.DatabasePerformanceMonitor() go monitor.DatabaseBackupMonitor() go monitor.QuotaMonitor() + go monitor.CockroachMonitor() select {} } diff --git a/service/go.work.sum b/service/go.work.sum index dce39ff6b4c..b0cfd473052 100644 --- a/service/go.work.sum +++ b/service/go.work.sum @@ -1,3 +1,4 @@ +cel.dev/expr v0.16.1 h1:NR0+oFYzR1CqLFhTAqg3ql59G9VfN8fKq1TCHJ6gq1g= cel.dev/expr v0.16.1/go.mod h1:AsGA5zb3WruAEQeQng1RZdGEXmBj0jvMWh6l5SnNuC8= cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -117,6 +118,7 @@ cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNF cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0 h1:PQcPefKFdaIzjQFbiyOgAqyx8q5djaE7x9Sqe712DPA= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/bigquery v1.50.0 h1:RscMV6LbnAmhAzD893Lv9nXXy2WCaJmbxYPWDLbGqNQ= cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= @@ -233,6 +235,7 @@ cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbH cloud.google.com/go/dataqna v0.8.4 h1:NJnu1kAPamZDs/if3bJ3+Wb6tjADHKL83NUWsaIp2zg= cloud.google.com/go/dataqna v0.8.4/go.mod h1:mySRKjKg5Lz784P6sCov3p1QD+RZQONRMRjzGNcFd0c= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/datastore v1.11.0 h1:iF6I/HaLs3Ado8uRKMvZRvF/ZLkWaWE9i8AiHzbC774= cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= @@ -291,6 +294,7 @@ cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466d cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4= cloud.google.com/go/filestore v1.8.0 h1:/+wUEGwk3x3Kxomi2cP5dsR8+SIXxo7M0THDjreFSYo= cloud.google.com/go/filestore v1.8.0/go.mod h1:S5JCxIbFjeBhWMTfIYH2Jx24J6BqjwpkkPl+nBA5DlI= +cloud.google.com/go/firestore v1.1.0 h1:9x7Bx0A9R5/M9jibeJeZWqjeVEIxYW9fZYqB9a70/bY= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/firestore v1.9.0 h1:IBlRyxgGySXu5VuW0RgGFlTtLukSnNkpDiEOMkQkmpA= cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= @@ -381,6 +385,7 @@ cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHS cloud.google.com/go/longrunning v0.5.2/go.mod h1:nqo6DQbNV2pXhGDbDMoN2bWz68MjZUzqv2YttZiveCs= cloud.google.com/go/longrunning v0.5.4 h1:w8xEcbZodnA2BbW6sVirkkoC+1gP8wS57EUUgGS0GVg= cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI= +cloud.google.com/go/longrunning v0.6.1 h1:lOLTFxYpr8hcRtcwWir5ITh1PAKUD/sG2lKrTSYjyMc= cloud.google.com/go/longrunning v0.6.1/go.mod h1:nHISoOZpBcmlwbJmiVk5oDRz0qG/ZxPynEGs1iZ79s0= cloud.google.com/go/managedidentities v1.5.0 h1:ZRQ4k21/jAhrHBVKl/AY7SjgzeJwG1iZa+mJ82P+VNg= cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= @@ -475,6 +480,7 @@ cloud.google.com/go/privatecatalog v0.9.4/go.mod h1:SOjm93f+5hp/U3PqMZAHTtBtluqL cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/pubsub v1.30.0 h1:vCge8m7aUKBJYOgrZp7EsNDf6QMd2CAlXZqWTn3yq6s= cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= @@ -576,6 +582,7 @@ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiy cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI= cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= @@ -611,6 +618,7 @@ cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV cloud.google.com/go/translate v1.8.2/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= cloud.google.com/go/translate v1.10.0 h1:tncNaKmlZnayMMRX/mMM2d5AJftecznnxVBD4w070NI= cloud.google.com/go/translate v1.10.0/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0= +cloud.google.com/go/translate v1.10.3 h1:g+B29z4gtRGsiKDoTF+bNeH25bLRokAaElygX2FcZkE= cloud.google.com/go/translate v1.10.3/go.mod h1:GW0vC1qvPtd3pgtypCv4k4U8B7EdgK9/QEF2aJEUovs= cloud.google.com/go/video v1.15.0 h1:upIbnGI0ZgACm58HPjAeBMleW3sl5cT84AbYQ8PWOgM= cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= @@ -659,6 +667,7 @@ cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcP cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g= cloud.google.com/go/workflows v1.12.3 h1:qocsqETmLAl34mSa01hKZjcqAvt699gaoFbooGGMvaM= cloud.google.com/go/workflows v1.12.3/go.mod h1:fmOUeeqEwPzIU81foMjTRQIdwQHADi/vEr1cx9R1m5g= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= @@ -677,6 +686,7 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= @@ -722,8 +732,11 @@ github.com/apache/thrift v0.16.0 h1:qEy6UW60iVOlUy+b9ZR0d5WzUWYGOo4HfopoyBaNmoY= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/apecloud/kubeblocks v0.8.4 h1:8esK2e9iiziPXTlGXmX2uFTU/YGFXFvyvqnCBODqWM4= github.com/apecloud/kubeblocks v0.8.4/go.mod h1:xQpzfMy4V+WJI5IKBWB02qsKAlVR3nAE71CPkAs2uOs= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= @@ -731,18 +744,27 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/astaxie/beego v1.12.3 h1:SAQkdD2ePye+v8Gn1r4X6IKZM1wd28EyUOVQ3PDSOOQ= github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.19 h1:woXadbf0c7enQ2UGCi8gW/WuKmE0xIzxBF/eD94jMKQ= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.19/go.mod h1:zminj5ucw7w0r65bP6nhyOd3xL6veAUMc3ElGMoLVb4= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.4 h1:tHxQi/XHPK0ctd/wdOw0t7Xrc2OxcRCnVzv8lwWPu0c= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.4/go.mod h1:4GQbF1vJzG60poZqWatZlhP31y8PGCCVTvIGPdaaYJ0= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.5 h1:HJwZwRt2Z2Tdec+m+fPjvdmkq2s9Ra+VR0hjF7V2o40= github.com/aws/aws-sdk-go-v2/service/sso v1.24.5/go.mod h1:wrMCEwjFPms+V86TCQQeOxQF/If4vT44FGIOFiMC2ck= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.4 h1:zcx9LiGWZ6i6pjdcoE9oXAB6mUdeyC36Ia/QEiIvYdg= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.4/go.mod h1:Tp/ly1cTjRLGBBmNccFumbZ8oqpZlpdhFf80SrRh4is= +github.com/aws/aws-sdk-go-v2/service/sts v1.32.4 h1:yDxvkz3/uOKfxnv8YhzOi9m+2OGIxF+on3KOISbK5IU= github.com/aws/aws-sdk-go-v2/service/sts v1.32.4/go.mod h1:9XEUty5v5UAsMiFOBJrNibZgwCeOma73jgGwwhgffa8= +github.com/bazelbuild/rules_go v0.49.0 h1:5vCbuvy8Q11g41lseGJDc5vxhDjJtfxr6nM/IC4VmqM= github.com/bazelbuild/rules_go v0.49.0/go.mod h1:Dhcz716Kqg1RHNWos+N6MlXNkjNP2EwZQ0LukRKJfMs= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.4 h1:w/jqZtC9YD4DS/Vp9GhWfWcCpuAL58oTnLoI8vE9YHU= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= @@ -763,8 +785,11 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89 h1:aPflPkRFkVwbW6dmcVqfgwp1i+UWGFH6VgR1Jim5Ygc= github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= +github.com/chromedp/chromedp v0.9.2 h1:dKtNz4kApb06KuSXoTQIyUC2TrA0fhGDwNZf3bcgfKw= github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs= +github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic= github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= @@ -795,6 +820,7 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+g github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY= github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0= github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE= @@ -819,6 +845,7 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= @@ -843,13 +870,16 @@ github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1: github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM= github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= +github.com/envoyproxy/go-control-plane v0.13.0 h1:HzkeUz1Knt+3bK+8LG1bxOO/jzWZmdxpwC51i202les= github.com/envoyproxy/go-control-plane v0.13.0/go.mod h1:GRaKG3dwvFoTg4nj7aXdZnvMg4d7nvT/wl9WgVXn3Q8= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= @@ -862,8 +892,10 @@ github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyT github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df h1:Bao6dhmbTA1KFVxmJ6nBoMuOJit2yjEgLJpIMYpop0E= github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df/go.mod h1:GJr+FCSXshIwgHBtLglIg9M2l2kQSi6QjVAngtzI08Y= @@ -880,8 +912,11 @@ github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiU github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro= @@ -893,6 +928,7 @@ github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -903,6 +939,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= @@ -933,10 +970,13 @@ github.com/google/go-intervals v0.0.2 h1:FGrVEiUnTRKR8yE04qzXYaJMtnIYqobR5QbblK3 github.com/google/go-intervals v0.0.2/go.mod h1:MkaR3LNRfeKLPmqgJYs4E66z5InYjmCjbbr4TQlcT6Y= github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9 h1:OF1IPgv+F4NmqmJ98KTjdN97Vs1JxDPB3vbmYzV2dpk= github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= +github.com/google/go-pkcs11 v0.3.0 h1:PVRnTgtArZ3QQqTGtbtjtnIkzl2iY2kt24yqbrf7td8= github.com/google/go-pkcs11 v0.3.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= @@ -953,6 +993,7 @@ github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= @@ -991,40 +1032,58 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjd github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/hashicorp/consul/api v1.1.0 h1:BNQPM9ytxj6jbjjdRPioQ94T6YXriSopn0i8COv6SRA= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1 h1:LnuDWGNsoajlhGyHJvuWW6FVqRl8JOTPqS6CPTsYjhY= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1 h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= +github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20220517205856-0058ec4f073c h1:rwmN+hgiyp8QyBqzdEX43lTjKAxaqCrYHaU5op5P9J8= github.com/ianlancetaylor/demangle v0.0.0-20220517205856-0058ec4f073c/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465 h1:KwWnWVWCNtNq/ewIX7HIKnELmEx2nDP42yskD/pi7QE= github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -1039,6 +1098,7 @@ github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= @@ -1046,9 +1106,11 @@ github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2E github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= @@ -1058,11 +1120,14 @@ github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/knz/go-libedit v1.10.1 h1:0pHpWtx9vcvC0xGZqEQlQdfSQs7WRlAjuPvk3fOZDCo= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= github.com/labring/operator-sdk v1.0.1 h1:JS+j9nF0lihkPJnMYJBZrH7Kfp/dKB2cnbBRMfkmE+g= github.com/labring/operator-sdk v1.0.1/go.mod h1:velfQ6SyrLXBeAShetQyR7q1zJNd8vGO6jjzbKcofj8= +github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de h1:V53FWzU6KAZVi1tPp5UIsMoUWJ2/PNwYIDXnu7QuBCE= github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= @@ -1070,11 +1135,13 @@ github.com/lyft/protoc-gen-star/v2 v2.0.1 h1:keaAo8hRuAT0O3DfJ/wM3rufbAjGeJ1lAtW github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= github.com/lyft/protoc-gen-star/v2 v2.0.3 h1:/3+/2sWyXeMLzKd1bX+ixWKgEMsULrIivpDsuaF441o= github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= +github.com/lyft/protoc-gen-star/v2 v2.0.4-0.20230330145011-496ad1ac90a4 h1:sIXJOMrYnQZJu7OB7ANSF4MYri2fTEGIsRLz6LwI4xE= github.com/lyft/protoc-gen-star/v2 v2.0.4-0.20230330145011-496ad1ac90a4/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/matoous/go-nanoid v1.5.0 h1:VRorl6uCngneC4oUQqOYtO3S0H5QKFtKuKycFG3euek= +github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= @@ -1083,6 +1150,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= @@ -1098,10 +1166,15 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU= github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k= +github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0 h1:lfGJxY7ToLJQjHHwi0EX6uYBdK78egf954SQl13PQJc= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= @@ -1123,7 +1196,9 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86 h1:D6paGObi5Wud7xg83MaEFyjxQB1W5bz5d0IFppr+ymk= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c h1:bY6ktFuJkt+ZXkX0RChQch2FtHpWQLVS8Qo1YasiIVk= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= @@ -1147,7 +1222,9 @@ github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bl github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= +github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= @@ -1160,8 +1237,11 @@ github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0 github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig= github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= @@ -1174,6 +1254,7 @@ github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdU github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= @@ -1194,10 +1275,13 @@ github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0= github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646 h1:RpforrEYXWkmGwJHIGnLZ3tTWStkjVVstwzNGqxX2Ds= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= @@ -1210,10 +1294,13 @@ github.com/shirou/gopsutil/v3 v3.23.6 h1:5y46WPI9QBKBbK7EEccUPNXpJpNrvPuTD0O2zHE github.com/shirou/gopsutil/v3 v3.23.6/go.mod h1:j7QX50DrXYggrpN30W0Mo+I4/8U2UUIQrnrhqUeWrAU= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636 h1:aSISeOcal5irEhJd1M+IrApc0PdcN7e7Aj4yuEnOrfQ= github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU= github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -1231,6 +1318,7 @@ github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY52 github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= @@ -1248,6 +1336,7 @@ github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1Fof github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1374,6 +1463,7 @@ go.opentelemetry.io/otel/sdk v1.10.0 h1:jZ6K7sVn04kk/3DNUdJ4mqRlGDiXAVuIG+MMENpT go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= @@ -1436,6 +1526,7 @@ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= @@ -1575,6 +1666,7 @@ golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808 h1:+Kc94D8UVEVxJnLXp/+FMfqQARZtWHfVrcRtcG8aT3g= golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ= +golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= @@ -1647,6 +1739,7 @@ golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= @@ -1760,6 +1853,7 @@ google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cba google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405 h1:o4S3HvTUEXgRsNSUQsALDVog0O9F/U1JJlHmmUN8Uas= google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20241021214115-324edc3d5d38 h1:42FIsHvG4GOaVHLDMcy/YMqC4clCbgAPojbcA2hXp5w= google.golang.org/genproto/googleapis/bytestream v0.0.0-20241021214115-324edc3d5d38/go.mod h1:T8O3fECQbif8cez15vxAcjbwXxvL2xbnvbQ7ZfiMAMs= google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= @@ -1833,6 +1927,7 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.27.2/go.mod h1:ENmbocXfBT2ADujUXcBhHV55RIT31IIEvkntP6vZKS4= k8s.io/api v0.27.4/go.mod h1:O3smaaX15NfxjzILfiln1D8Z3+gEYpjEpiNA/1EVK1Y= @@ -1876,13 +1971,21 @@ k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= +modernc.org/ccgo/v3 v3.17.0 h1:o3OmOqx4/OFnl4Vm3G8Bgmqxnvxnh0nbxeT5p/dWChA= modernc.org/ccgo/v3 v3.17.0/go.mod h1:Sg3fwVpmLvCUTaqEUjiBDAvshIaKDB0RXaf+zgqFu8I= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +nullprogram.com/x/optparse v1.0.0 h1:xGFgVi5ZaWOnYdac2foDT3vg0ZZC9ErXFV57mr4OHrI= +rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= +rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 h1:trsWhjU5jZrx6UvFu4WzQDrN7Pga4a7Qg+zcfcj64PA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2/go.mod h1:+qG7ISXqCDVVcyO8hLn12AKVYYUjM7ftlqsqmrhMZE0=